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 <stdio.h> 31 #include <stdarg.h> 32 #include <inttypes.h> 33 34 #include <sepol/policydb/conditional.h> 35 36 #include "cil_internal.h" 37 #include "cil_flavor.h" 38 #include "cil_log.h" 39 #include "cil_tree.h" 40 #include "cil_list.h" 41 #include "cil_parser.h" 42 #include "cil_strpool.h" 43 44 void cil_tree_print_perms_list(struct cil_tree_node *current_perm); 45 void cil_tree_print_classperms(struct cil_classperms *cp); 46 void cil_tree_print_level(struct cil_level *level); 47 void cil_tree_print_levelrange(struct cil_levelrange *lvlrange); 48 void cil_tree_print_context(struct cil_context *context); 49 void cil_tree_print_expr_tree(struct cil_tree_node *expr_root); 50 void cil_tree_print_constrain(struct cil_constrain *cons); 51 void cil_tree_print_node(struct cil_tree_node *node); 52 53 __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_error(const char* msg, ...) 54 { 55 va_list ap; 56 va_start(ap, msg); 57 cil_vlog(CIL_ERR, msg, ap); 58 va_end(ap); 59 exit(1); 60 } 61 62 struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil) 63 { 64 if (!node) { 65 return NULL; 66 } 67 68 node = node->parent; 69 70 while (node) { 71 if (node->flavor == CIL_NODE && node->data == NULL) { 72 if (node->cl_head->data == CIL_KEY_SRC_INFO) { 73 /* Parse Tree */ 74 *path = node->cl_head->next->next->data; 75 *is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL); 76 return node; 77 } 78 node = node->parent; 79 } else if (node->flavor == CIL_SRC_INFO) { 80 /* AST */ 81 struct cil_src_info *info = node->data; 82 *path = info->path; 83 *is_cil = info->is_cil; 84 return node; 85 } else { 86 if (node->flavor == CIL_CALL) { 87 struct cil_call *call = node->data; 88 node = NODE(call->macro); 89 } else if (node->flavor == CIL_BLOCKINHERIT) { 90 struct cil_blockinherit *inherit = node->data; 91 node = NODE(inherit->block); 92 } else { 93 node = node->parent; 94 } 95 } 96 } 97 98 return NULL; 99 } 100 101 char *cil_tree_get_cil_path(struct cil_tree_node *node) 102 { 103 char *path = NULL; 104 int is_cil; 105 106 while (node) { 107 node = cil_tree_get_next_path(node, &path, &is_cil); 108 if (node && is_cil) { 109 return path; 110 } 111 } 112 113 return NULL; 114 } 115 116 __attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...) 117 { 118 va_list ap; 119 120 va_start(ap, msg); 121 cil_vlog(lvl, msg, ap); 122 va_end(ap); 123 124 if (node) { 125 char *path = NULL; 126 int is_cil; 127 unsigned hll_line = node->hll_line; 128 129 path = cil_tree_get_cil_path(node); 130 131 if (path != NULL) { 132 cil_log(lvl, " at %s:%d", path, node->line); 133 } 134 135 while (node) { 136 node = cil_tree_get_next_path(node, &path, &is_cil); 137 if (node && !is_cil) { 138 cil_log(lvl," from %s:%d", path, hll_line); 139 path = NULL; 140 hll_line = node->hll_line; 141 } 142 } 143 } 144 145 cil_log(lvl,"\n"); 146 } 147 148 int cil_tree_init(struct cil_tree **tree) 149 { 150 struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree)); 151 152 cil_tree_node_init(&new_tree->root); 153 154 *tree = new_tree; 155 156 return SEPOL_OK; 157 } 158 159 void cil_tree_destroy(struct cil_tree **tree) 160 { 161 if (tree == NULL || *tree == NULL) { 162 return; 163 } 164 165 cil_tree_subtree_destroy((*tree)->root); 166 free(*tree); 167 *tree = NULL; 168 } 169 170 void cil_tree_subtree_destroy(struct cil_tree_node *node) 171 { 172 cil_tree_children_destroy(node); 173 cil_tree_node_destroy(&node); 174 } 175 176 void cil_tree_children_destroy(struct cil_tree_node *node) 177 { 178 struct cil_tree_node *start_node = node; 179 struct cil_tree_node *next = NULL; 180 181 if (node == NULL) { 182 return; 183 } 184 185 if (node->cl_head != NULL) { 186 node = node->cl_head; 187 } 188 189 while (node != start_node) { 190 if (node->cl_head != NULL){ 191 next = node->cl_head; 192 } else { 193 if (node->next == NULL) { 194 next = node->parent; 195 if (node->parent != NULL) { 196 node->parent->cl_head = NULL; 197 } 198 cil_tree_node_destroy(&node); 199 } else { 200 next = node->next; 201 cil_tree_node_destroy(&node); 202 } 203 } 204 node = next; 205 } 206 } 207 208 void cil_tree_node_init(struct cil_tree_node **node) 209 { 210 struct cil_tree_node *new_node = cil_malloc(sizeof(*new_node)); 211 new_node->cl_head = NULL; 212 new_node->cl_tail = NULL; 213 new_node->parent = NULL; 214 new_node->data = NULL; 215 new_node->next = NULL; 216 new_node->flavor = CIL_ROOT; 217 new_node->line = 0; 218 new_node->hll_line = 0; 219 220 *node = new_node; 221 } 222 223 void cil_tree_node_destroy(struct cil_tree_node **node) 224 { 225 struct cil_symtab_datum *datum; 226 227 if (node == NULL || *node == NULL) { 228 return; 229 } 230 231 if ((*node)->flavor >= CIL_MIN_DECLARATIVE) { 232 datum = (*node)->data; 233 cil_symtab_datum_remove_node(datum, *node); 234 if (datum->nodes == NULL) { 235 cil_destroy_data(&(*node)->data, (*node)->flavor); 236 } 237 } else { 238 cil_destroy_data(&(*node)->data, (*node)->flavor); 239 } 240 free(*node); 241 *node = NULL; 242 } 243 244 /* Perform depth-first walk of the tree 245 Parameters: 246 start_node: root node to start walking from 247 process_node: function to call when visiting a node 248 Takes parameters: 249 node: node being visited 250 finished: boolean indicating to the tree walker that it should move on from this branch 251 extra_args: additional data 252 first_child: Function to call before entering list of children 253 Takes parameters: 254 node: node of first child 255 extra args: additional data 256 last_child: Function to call when finished with the last child of a node's children 257 extra_args: any additional data to be passed to the helper functions 258 */ 259 260 int cil_tree_walk_core(struct cil_tree_node *node, 261 int (*process_node)(struct cil_tree_node *node, uint32_t *finished, void *extra_args), 262 int (*first_child)(struct cil_tree_node *node, void *extra_args), 263 int (*last_child)(struct cil_tree_node *node, void *extra_args), 264 void *extra_args) 265 { 266 int rc = SEPOL_ERR; 267 268 while (node) { 269 uint32_t finished = CIL_TREE_SKIP_NOTHING; 270 271 if (process_node != NULL) { 272 rc = (*process_node)(node, &finished, extra_args); 273 if (rc != SEPOL_OK) { 274 cil_tree_log(node, CIL_INFO, "Problem"); 275 return rc; 276 } 277 } 278 279 if (finished & CIL_TREE_SKIP_NEXT) { 280 return SEPOL_OK; 281 } 282 283 if (node->cl_head != NULL && !(finished & CIL_TREE_SKIP_HEAD)) { 284 rc = cil_tree_walk(node, process_node, first_child, last_child, extra_args); 285 if (rc != SEPOL_OK) { 286 return rc; 287 } 288 } 289 290 node = node->next; 291 } 292 293 return SEPOL_OK; 294 } 295 296 int cil_tree_walk(struct cil_tree_node *node, 297 int (*process_node)(struct cil_tree_node *node, uint32_t *finished, void *extra_args), 298 int (*first_child)(struct cil_tree_node *node, void *extra_args), 299 int (*last_child)(struct cil_tree_node *node, void *extra_args), 300 void *extra_args) 301 { 302 int rc = SEPOL_ERR; 303 304 if (!node || !node->cl_head) { 305 return SEPOL_OK; 306 } 307 308 if (first_child != NULL) { 309 rc = (*first_child)(node->cl_head, extra_args); 310 if (rc != SEPOL_OK) { 311 cil_tree_log(node, CIL_INFO, "Problem"); 312 return rc; 313 } 314 } 315 316 rc = cil_tree_walk_core(node->cl_head, process_node, first_child, last_child, extra_args); 317 if (rc != SEPOL_OK) { 318 return rc; 319 } 320 321 if (last_child != NULL) { 322 rc = (*last_child)(node->cl_tail, extra_args); 323 if (rc != SEPOL_OK) { 324 cil_tree_log(node, CIL_INFO, "Problem"); 325 return rc; 326 } 327 } 328 329 return SEPOL_OK; 330 } 331 332 333 /* Copied from cil_policy.c, but changed to prefix -- Need to refactor */ 334 static int cil_expr_to_string(struct cil_list *expr, char **out) 335 { 336 int rc = SEPOL_ERR; 337 struct cil_list_item *curr; 338 char *stack[COND_EXPR_MAXDEPTH] = {}; 339 int pos = 0; 340 341 cil_list_for_each(curr, expr) { 342 if (pos > COND_EXPR_MAXDEPTH) { 343 rc = SEPOL_ERR; 344 goto exit; 345 } 346 switch (curr->flavor) { 347 case CIL_LIST: 348 rc = cil_expr_to_string(curr->data, &stack[pos]); 349 if (rc != SEPOL_OK) { 350 goto exit; 351 } 352 pos++; 353 break; 354 case CIL_STRING: 355 stack[pos] = curr->data; 356 pos++; 357 break; 358 case CIL_DATUM: 359 stack[pos] = ((struct cil_symtab_datum *)curr->data)->name; 360 pos++; 361 break; 362 case CIL_OP: { 363 int len; 364 char *expr_str; 365 enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); 366 char *op_str = NULL; 367 368 if (pos == 0) { 369 rc = SEPOL_ERR; 370 goto exit; 371 } 372 switch (op_flavor) { 373 case CIL_AND: 374 op_str = CIL_KEY_AND; 375 break; 376 case CIL_OR: 377 op_str = CIL_KEY_OR; 378 break; 379 case CIL_NOT: 380 op_str = CIL_KEY_NOT; 381 break; 382 case CIL_ALL: 383 op_str = CIL_KEY_ALL; 384 break; 385 case CIL_EQ: 386 op_str = CIL_KEY_EQ; 387 break; 388 case CIL_NEQ: 389 op_str = CIL_KEY_NEQ; 390 break; 391 case CIL_XOR: 392 op_str = CIL_KEY_XOR; 393 break; 394 case CIL_RANGE: 395 op_str = CIL_KEY_RANGE; 396 break; 397 case CIL_CONS_DOM: 398 op_str = CIL_KEY_CONS_DOM; 399 break; 400 case CIL_CONS_DOMBY: 401 op_str = CIL_KEY_CONS_DOMBY; 402 break; 403 case CIL_CONS_INCOMP: 404 op_str = CIL_KEY_CONS_INCOMP; 405 break; 406 default: 407 cil_log(CIL_ERR, "Unknown operator in expression\n"); 408 goto exit; 409 break; 410 } 411 if (op_flavor == CIL_NOT) { 412 len = strlen(stack[pos-1]) + strlen(op_str) + 4; 413 expr_str = cil_malloc(len); 414 snprintf(expr_str, len, "(%s %s)", op_str, stack[pos-1]); 415 free(stack[pos-1]); 416 stack[pos-1] = NULL; 417 pos--; 418 } else { 419 if (pos < 2) { 420 rc = SEPOL_ERR; 421 goto exit; 422 } 423 len = strlen(stack[pos-1]) + strlen(stack[pos-2]) + strlen(op_str) + 5; 424 expr_str = cil_malloc(len); 425 snprintf(expr_str, len, "(%s %s %s)", op_str, stack[pos-1], stack[pos-2]); 426 free(stack[pos-2]); 427 free(stack[pos-1]); 428 stack[pos-2] = NULL; 429 stack[pos-1] = NULL; 430 pos -= 2; 431 } 432 stack[pos] = expr_str; 433 pos++; 434 break; 435 } 436 case CIL_CONS_OPERAND: { 437 enum cil_flavor operand_flavor = *((enum cil_flavor *)curr->data); 438 char *operand_str = NULL; 439 switch (operand_flavor) { 440 case CIL_CONS_U1: 441 operand_str = CIL_KEY_CONS_U1; 442 break; 443 case CIL_CONS_U2: 444 operand_str = CIL_KEY_CONS_U2; 445 break; 446 case CIL_CONS_U3: 447 operand_str = CIL_KEY_CONS_U3; 448 break; 449 case CIL_CONS_T1: 450 operand_str = CIL_KEY_CONS_T1; 451 break; 452 case CIL_CONS_T2: 453 operand_str = CIL_KEY_CONS_T2; 454 break; 455 case CIL_CONS_T3: 456 operand_str = CIL_KEY_CONS_T3; 457 break; 458 case CIL_CONS_R1: 459 operand_str = CIL_KEY_CONS_R1; 460 break; 461 case CIL_CONS_R2: 462 operand_str = CIL_KEY_CONS_R2; 463 break; 464 case CIL_CONS_R3: 465 operand_str = CIL_KEY_CONS_R3; 466 break; 467 case CIL_CONS_L1: 468 operand_str = CIL_KEY_CONS_L1; 469 break; 470 case CIL_CONS_L2: 471 operand_str = CIL_KEY_CONS_L2; 472 break; 473 case CIL_CONS_H1: 474 operand_str = CIL_KEY_CONS_H1; 475 break; 476 case CIL_CONS_H2: 477 operand_str = CIL_KEY_CONS_H2; 478 break; 479 default: 480 cil_log(CIL_ERR, "Unknown operand in expression\n"); 481 goto exit; 482 break; 483 } 484 stack[pos] = operand_str; 485 pos++; 486 break; 487 } 488 default: 489 cil_log(CIL_ERR, "Unknown flavor in expression\n"); 490 goto exit; 491 break; 492 } 493 } 494 495 *out = stack[0]; 496 497 return SEPOL_OK; 498 499 exit: 500 return rc; 501 } 502 503 void cil_tree_print_expr(struct cil_list *datum_expr, struct cil_list *str_expr) 504 { 505 char *expr_str; 506 507 cil_log(CIL_INFO, "("); 508 509 if (datum_expr != NULL) { 510 cil_expr_to_string(datum_expr, &expr_str); 511 } else { 512 cil_expr_to_string(str_expr, &expr_str); 513 } 514 515 cil_log(CIL_INFO, "%s)", expr_str); 516 free(expr_str); 517 } 518 519 void cil_tree_print_perms_list(struct cil_tree_node *current_perm) 520 { 521 while (current_perm != NULL) { 522 if (current_perm->flavor == CIL_PERM) { 523 cil_log(CIL_INFO, " %s", ((struct cil_perm *)current_perm->data)->datum.name); 524 } else if (current_perm->flavor == CIL_MAP_PERM) { 525 cil_log(CIL_INFO, " %s", ((struct cil_perm*)current_perm->data)->datum.name); 526 } else { 527 cil_log(CIL_INFO, "\n\n perms list contained unexpected data type: %d\n", current_perm->flavor); 528 break; 529 } 530 current_perm = current_perm->next; 531 } 532 } 533 534 void cil_tree_print_cats(struct cil_cats *cats) 535 { 536 cil_tree_print_expr(cats->datum_expr, cats->str_expr); 537 } 538 539 void cil_tree_print_perm_strs(struct cil_list *perm_strs) 540 { 541 struct cil_list_item *curr; 542 543 if (perm_strs == NULL) { 544 return; 545 } 546 547 cil_log(CIL_INFO, " ("); 548 549 cil_list_for_each(curr, perm_strs) { 550 cil_log(CIL_INFO, " %s", (char*)curr->data); 551 } 552 553 cil_log(CIL_INFO, " )"); 554 } 555 556 557 void cil_tree_print_classperms(struct cil_classperms *cp) 558 { 559 if (cp == NULL) { 560 return; 561 } 562 563 cil_log(CIL_INFO, " class: %s", cp->class_str); 564 cil_log(CIL_INFO, ", perm_strs:"); 565 cil_tree_print_perm_strs(cp->perm_strs); 566 } 567 568 void cil_tree_print_classperms_set(struct cil_classperms_set *cp_set) 569 { 570 if (cp_set == NULL) { 571 return; 572 } 573 574 cil_log(CIL_INFO, " %s", cp_set->set_str); 575 } 576 577 void cil_tree_print_classperms_list(struct cil_list *cp_list) 578 { 579 struct cil_list_item *i; 580 581 if (cp_list == NULL) { 582 return; 583 } 584 585 cil_list_for_each(i, cp_list) { 586 if (i->flavor == CIL_CLASSPERMS) { 587 cil_tree_print_classperms(i->data); 588 } else { 589 cil_tree_print_classperms_set(i->data); 590 } 591 } 592 } 593 594 void cil_tree_print_level(struct cil_level *level) 595 { 596 if (level->sens != NULL) { 597 cil_log(CIL_INFO, " %s", level->sens->datum.name); 598 } else if (level->sens_str != NULL) { 599 cil_log(CIL_INFO, " %s", level->sens_str); 600 } 601 602 cil_tree_print_cats(level->cats); 603 604 return; 605 } 606 607 void cil_tree_print_levelrange(struct cil_levelrange *lvlrange) 608 { 609 cil_log(CIL_INFO, " ("); 610 if (lvlrange->low != NULL) { 611 cil_log(CIL_INFO, " ("); 612 cil_tree_print_level(lvlrange->low); 613 cil_log(CIL_INFO, " )"); 614 } else if (lvlrange->low_str != NULL) { 615 cil_log(CIL_INFO, " %s", lvlrange->low_str); 616 } 617 618 if (lvlrange->high != NULL) { 619 cil_log(CIL_INFO, " ("); 620 cil_tree_print_level(lvlrange->high); 621 cil_log(CIL_INFO, " )"); 622 } else if (lvlrange->high_str != NULL) { 623 cil_log(CIL_INFO, " %s", lvlrange->high_str); 624 } 625 cil_log(CIL_INFO, " )"); 626 } 627 628 void cil_tree_print_context(struct cil_context *context) 629 { 630 cil_log(CIL_INFO, " ("); 631 if (context->user != NULL) { 632 cil_log(CIL_INFO, " %s", context->user->datum.name); 633 } else if (context->user_str != NULL) { 634 cil_log(CIL_INFO, " %s", context->user_str); 635 } 636 637 if (context->role != NULL) { 638 cil_log(CIL_INFO, " %s", context->role->datum.name); 639 } else if (context->role_str != NULL) { 640 cil_log(CIL_INFO, " %s", context->role_str); 641 } 642 643 if (context->type != NULL) { 644 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)context->type)->name); 645 } else if (context->type_str != NULL) { 646 cil_log(CIL_INFO, " %s", context->type_str); 647 } 648 649 if (context->range != NULL) { 650 cil_tree_print_levelrange(context->range); 651 } else if (context->range_str != NULL) { 652 cil_log(CIL_INFO, " %s", context->range_str); 653 } 654 655 cil_log(CIL_INFO, " )"); 656 657 return; 658 } 659 660 void cil_tree_print_constrain(struct cil_constrain *cons) 661 { 662 cil_tree_print_classperms_list(cons->classperms); 663 664 cil_tree_print_expr(cons->datum_expr, cons->str_expr); 665 666 cil_log(CIL_INFO, "\n"); 667 } 668 669 void cil_tree_print_node(struct cil_tree_node *node) 670 { 671 if (node->data == NULL) { 672 cil_log(CIL_INFO, "FLAVOR: %d", node->flavor); 673 return; 674 } else { 675 switch( node->flavor ) { 676 case CIL_BLOCK: { 677 struct cil_block *block = node->data; 678 cil_log(CIL_INFO, "BLOCK: %s\n", block->datum.name); 679 return; 680 } 681 case CIL_BLOCKINHERIT: { 682 struct cil_blockinherit *inherit = node->data; 683 cil_log(CIL_INFO, "BLOCKINHERIT: %s\n", inherit->block_str); 684 return; 685 } 686 case CIL_BLOCKABSTRACT: { 687 struct cil_blockabstract *abstract = node->data; 688 cil_log(CIL_INFO, "BLOCKABSTRACT: %s\n", abstract->block_str); 689 return; 690 } 691 case CIL_IN: { 692 struct cil_in *in = node->data; 693 cil_log(CIL_INFO, "IN: %s\n", in->block_str); 694 return; 695 } 696 case CIL_USER: { 697 struct cil_user *user = node->data; 698 cil_log(CIL_INFO, "USER: %s\n", user->datum.name); 699 return; 700 } 701 case CIL_TYPE: { 702 struct cil_type *type = node->data; 703 cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name); 704 return; 705 } 706 case CIL_EXPANDTYPEATTRIBUTE: { 707 struct cil_expandtypeattribute *attr = node->data; 708 709 fprintf(stderr, "%s %u\n", __func__, __LINE__); 710 cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE "); 711 cil_tree_print_expr(attr->attr_datums, attr->attr_strs); 712 cil_log(CIL_INFO, "%s)\n",attr->expand ? 713 CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE); 714 715 return; 716 } 717 case CIL_TYPEATTRIBUTESET: { 718 struct cil_typeattributeset *attr = node->data; 719 720 cil_log(CIL_INFO, "(TYPEATTRIBUTESET %s ", attr->attr_str); 721 722 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 723 724 cil_log(CIL_INFO, "\n"); 725 return; 726 } 727 case CIL_TYPEATTRIBUTE: { 728 struct cil_typeattribute *attr = node->data; 729 cil_log(CIL_INFO, "TYPEATTRIBUTE: %s\n", attr->datum.name); 730 return; 731 } 732 case CIL_ROLE: { 733 struct cil_role *role = node->data; 734 cil_log(CIL_INFO, "ROLE: %s\n", role->datum.name); 735 return; 736 } 737 case CIL_USERROLE: { 738 struct cil_userrole *userrole = node->data; 739 cil_log(CIL_INFO, "USERROLE:"); 740 struct cil_symtab_datum *datum = NULL; 741 742 if (userrole->user != NULL) { 743 datum = userrole->user; 744 cil_log(CIL_INFO, " %s", datum->name); 745 } else if (userrole->user_str != NULL) { 746 cil_log(CIL_INFO, " %s", userrole->user_str); 747 } 748 749 if (userrole->role != NULL) { 750 datum = userrole->role; 751 cil_log(CIL_INFO, " %s", datum->name); 752 } else if (userrole->role_str != NULL) { 753 cil_log(CIL_INFO, " %s", userrole->role_str); 754 } 755 756 cil_log(CIL_INFO, "\n"); 757 return; 758 } 759 case CIL_USERLEVEL: { 760 struct cil_userlevel *usrlvl = node->data; 761 cil_log(CIL_INFO, "USERLEVEL:"); 762 763 if (usrlvl->user_str != NULL) { 764 cil_log(CIL_INFO, " %s", usrlvl->user_str); 765 } 766 767 if (usrlvl->level != NULL) { 768 cil_log(CIL_INFO, " ("); 769 cil_tree_print_level(usrlvl->level); 770 cil_log(CIL_INFO, " )"); 771 } else if (usrlvl->level_str != NULL) { 772 cil_log(CIL_INFO, " %s", usrlvl->level_str); 773 } 774 775 cil_log(CIL_INFO, "\n"); 776 return; 777 } 778 case CIL_USERRANGE: { 779 struct cil_userrange *userrange = node->data; 780 cil_log(CIL_INFO, "USERRANGE:"); 781 782 if (userrange->user_str != NULL) { 783 cil_log(CIL_INFO, " %s", userrange->user_str); 784 } 785 786 if (userrange->range != NULL) { 787 cil_log(CIL_INFO, " ("); 788 cil_tree_print_levelrange(userrange->range); 789 cil_log(CIL_INFO, " )"); 790 } else if (userrange->range_str != NULL) { 791 cil_log(CIL_INFO, " %s", userrange->range_str); 792 } 793 794 cil_log(CIL_INFO, "\n"); 795 return; 796 } 797 case CIL_USERBOUNDS: { 798 struct cil_bounds *bnds = node->data; 799 cil_log(CIL_INFO, "USERBOUNDS: user: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 800 return; 801 } 802 case CIL_ROLETYPE: { 803 struct cil_roletype *roletype = node->data; 804 struct cil_symtab_datum *datum = NULL; 805 cil_log(CIL_INFO, "ROLETYPE:"); 806 807 if (roletype->role != NULL) { 808 datum = roletype->role; 809 cil_log(CIL_INFO, " %s", datum->name); 810 } else if (roletype->role_str != NULL) { 811 cil_log(CIL_INFO, " %s", roletype->role_str); 812 } 813 814 if (roletype->type != NULL) { 815 datum = roletype->type; 816 cil_log(CIL_INFO, " %s", datum->name); 817 } else if (roletype->type_str != NULL) { 818 cil_log(CIL_INFO, " %s", roletype->type_str); 819 } 820 821 cil_log(CIL_INFO, "\n"); 822 return; 823 } 824 case CIL_ROLETRANSITION: { 825 struct cil_roletransition *roletrans = node->data; 826 cil_log(CIL_INFO, "ROLETRANSITION:"); 827 828 if (roletrans->src != NULL) { 829 cil_log(CIL_INFO, " %s", roletrans->src->datum.name); 830 } else { 831 cil_log(CIL_INFO, " %s", roletrans->src_str); 832 } 833 834 if (roletrans->tgt != NULL) { 835 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)roletrans->tgt)->name); 836 } else { 837 cil_log(CIL_INFO, " %s", roletrans->tgt_str); 838 } 839 840 if (roletrans->obj != NULL) { 841 cil_log(CIL_INFO, " %s", roletrans->obj->datum.name); 842 } else { 843 cil_log(CIL_INFO, " %s", roletrans->obj_str); 844 } 845 846 if (roletrans->result != NULL) { 847 cil_log(CIL_INFO, " %s\n", roletrans->result->datum.name); 848 } else { 849 cil_log(CIL_INFO, " %s\n", roletrans->result_str); 850 } 851 852 return; 853 } 854 case CIL_ROLEALLOW: { 855 struct cil_roleallow *roleallow = node->data; 856 cil_log(CIL_INFO, "ROLEALLOW:"); 857 858 if (roleallow->src != NULL) { 859 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->src)->name); 860 } else { 861 cil_log(CIL_INFO, " %s", roleallow->src_str); 862 } 863 864 if (roleallow->tgt != NULL) { 865 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->tgt)->name); 866 } else { 867 cil_log(CIL_INFO, " %s", roleallow->tgt_str); 868 } 869 870 cil_log(CIL_INFO, "\n"); 871 return; 872 } 873 case CIL_ROLEATTRIBUTESET: { 874 struct cil_roleattributeset *attr = node->data; 875 876 cil_log(CIL_INFO, "(ROLEATTRIBUTESET %s ", attr->attr_str); 877 878 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 879 880 cil_log(CIL_INFO, "\n"); 881 return; 882 } 883 case CIL_ROLEATTRIBUTE: { 884 struct cil_roleattribute *attr = node->data; 885 cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name); 886 return; 887 } 888 case CIL_USERATTRIBUTESET: { 889 struct cil_userattributeset *attr = node->data; 890 891 cil_log(CIL_INFO, "(USERATTRIBUTESET %s ", attr->attr_str); 892 893 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 894 895 cil_log(CIL_INFO, "\n"); 896 return; 897 } 898 case CIL_USERATTRIBUTE: { 899 struct cil_userattribute *attr = node->data; 900 cil_log(CIL_INFO, "USERATTRIBUTE: %s\n", attr->datum.name); 901 return; 902 } 903 case CIL_ROLEBOUNDS: { 904 struct cil_bounds *bnds = node->data; 905 cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 906 return; 907 } 908 case CIL_CLASS: { 909 struct cil_class *cls = node->data; 910 cil_log(CIL_INFO, "CLASS: %s ", cls->datum.name); 911 912 if (cls->common != NULL) { 913 cil_log(CIL_INFO, "inherits: %s ", cls->common->datum.name); 914 } 915 cil_log(CIL_INFO, "("); 916 917 cil_tree_print_perms_list(node->cl_head); 918 919 cil_log(CIL_INFO, " )"); 920 return; 921 } 922 case CIL_CLASSORDER: { 923 struct cil_classorder *classorder = node->data; 924 struct cil_list_item *class; 925 926 if (classorder->class_list_str == NULL) { 927 cil_log(CIL_INFO, "CLASSORDER: ()\n"); 928 return; 929 } 930 931 cil_log(CIL_INFO, "CLASSORDER: ("); 932 cil_list_for_each(class, classorder->class_list_str) { 933 cil_log(CIL_INFO, " %s", (char*)class->data); 934 } 935 cil_log(CIL_INFO, " )\n"); 936 return; 937 } 938 case CIL_COMMON: { 939 struct cil_class *common = node->data; 940 cil_log(CIL_INFO, "COMMON: %s (", common->datum.name); 941 942 cil_tree_print_perms_list(node->cl_head); 943 944 cil_log(CIL_INFO, " )"); 945 return; 946 } 947 case CIL_CLASSCOMMON: { 948 struct cil_classcommon *clscom = node->data; 949 950 cil_log(CIL_INFO, "CLASSCOMMON: class: %s, common: %s\n", clscom->class_str, clscom->common_str); 951 952 return; 953 } 954 case CIL_CLASSPERMISSION: { 955 struct cil_classpermission *cp = node->data; 956 957 cil_log(CIL_INFO, "CLASSPERMISSION: %s", cp->datum.name); 958 959 cil_log(CIL_INFO, "\n"); 960 961 return; 962 } 963 case CIL_CLASSPERMISSIONSET: { 964 struct cil_classpermissionset *cps = node->data; 965 966 cil_log(CIL_INFO, "CLASSPERMISSIONSET: %s", cps->set_str); 967 968 cil_tree_print_classperms_list(cps->classperms); 969 970 cil_log(CIL_INFO, "\n"); 971 972 return; 973 } 974 case CIL_MAP_CLASS: { 975 struct cil_class *cm = node->data; 976 cil_log(CIL_INFO, "MAP_CLASS: %s", cm->datum.name); 977 978 cil_log(CIL_INFO, " ("); 979 cil_tree_print_perms_list(node->cl_head); 980 cil_log(CIL_INFO, " )\n"); 981 982 return; 983 } 984 case CIL_MAP_PERM: { 985 struct cil_perm *cmp = node->data; 986 987 cil_log(CIL_INFO, "MAP_PERM: %s", cmp->datum.name); 988 989 if (cmp->classperms == NULL) { 990 cil_log(CIL_INFO, " perms: ()"); 991 return; 992 } 993 994 cil_log(CIL_INFO, " kernel class perms: ("); 995 996 cil_tree_print_classperms_list(cmp->classperms); 997 998 cil_log(CIL_INFO, " )\n"); 999 1000 return; 1001 } 1002 case CIL_CLASSMAPPING: { 1003 struct cil_classmapping *mapping = node->data; 1004 1005 cil_log(CIL_INFO, "CLASSMAPPING: map class: %s, map perm: %s,", mapping->map_class_str, mapping->map_perm_str); 1006 1007 cil_log(CIL_INFO, " ("); 1008 1009 cil_tree_print_classperms_list(mapping->classperms); 1010 1011 cil_log(CIL_INFO, " )\n"); 1012 return; 1013 } 1014 case CIL_BOOL: { 1015 struct cil_bool *boolean = node->data; 1016 cil_log(CIL_INFO, "BOOL: %s, value: %d\n", boolean->datum.name, boolean->value); 1017 return; 1018 } 1019 case CIL_TUNABLE: { 1020 struct cil_tunable *tunable = node->data; 1021 cil_log(CIL_INFO, "TUNABLE: %s, value: %d\n", tunable->datum.name, tunable->value); 1022 return; 1023 } 1024 case CIL_BOOLEANIF: { 1025 struct cil_booleanif *bif = node->data; 1026 1027 cil_log(CIL_INFO, "(BOOLEANIF "); 1028 1029 cil_tree_print_expr(bif->datum_expr, bif->str_expr); 1030 1031 cil_log(CIL_INFO, " )\n"); 1032 return; 1033 } 1034 case CIL_TUNABLEIF: { 1035 struct cil_tunableif *tif = node->data; 1036 1037 cil_log(CIL_INFO, "(TUNABLEIF "); 1038 1039 cil_tree_print_expr(tif->datum_expr, tif->str_expr); 1040 1041 cil_log(CIL_INFO, " )\n"); 1042 return; 1043 } 1044 case CIL_CONDBLOCK: { 1045 struct cil_condblock *cb = node->data; 1046 if (cb->flavor == CIL_CONDTRUE) { 1047 cil_log(CIL_INFO, "true\n"); 1048 } else if (cb->flavor == CIL_CONDFALSE) { 1049 cil_log(CIL_INFO, "false\n"); 1050 } 1051 return; 1052 } 1053 case CIL_ALL: 1054 cil_log(CIL_INFO, "all"); 1055 return; 1056 case CIL_AND: 1057 cil_log(CIL_INFO, "&&"); 1058 return; 1059 case CIL_OR: 1060 cil_log(CIL_INFO, "|| "); 1061 return; 1062 case CIL_NOT: 1063 cil_log(CIL_INFO, "!"); 1064 return; 1065 case CIL_EQ: 1066 cil_log(CIL_INFO, "=="); 1067 return; 1068 case CIL_NEQ: 1069 cil_log(CIL_INFO, "!="); 1070 return; 1071 case CIL_TYPEALIAS: { 1072 struct cil_alias *alias = node->data; 1073 cil_log(CIL_INFO, "TYPEALIAS: %s\n", alias->datum.name); 1074 return; 1075 } 1076 case CIL_TYPEALIASACTUAL: { 1077 struct cil_aliasactual *aliasactual = node->data; 1078 cil_log(CIL_INFO, "TYPEALIASACTUAL: type: %s, alias: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1079 return; 1080 } 1081 case CIL_TYPEBOUNDS: { 1082 struct cil_bounds *bnds = node->data; 1083 cil_log(CIL_INFO, "TYPEBOUNDS: type: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 1084 return; 1085 } 1086 case CIL_TYPEPERMISSIVE: { 1087 struct cil_typepermissive *typeperm = node->data; 1088 1089 if (typeperm->type != NULL) { 1090 cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", ((struct cil_symtab_datum *)typeperm->type)->name); 1091 } else { 1092 cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", typeperm->type_str); 1093 } 1094 1095 return; 1096 } 1097 case CIL_NAMETYPETRANSITION: { 1098 struct cil_nametypetransition *nametypetrans = node->data; 1099 cil_log(CIL_INFO, "TYPETRANSITION:"); 1100 1101 if (nametypetrans->src != NULL) { 1102 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->src)->name); 1103 } else { 1104 cil_log(CIL_INFO, " %s", nametypetrans->src_str); 1105 } 1106 1107 if (nametypetrans->tgt != NULL) { 1108 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->tgt)->name); 1109 } else { 1110 cil_log(CIL_INFO, " %s", nametypetrans->tgt_str); 1111 } 1112 1113 if (nametypetrans->obj != NULL) { 1114 cil_log(CIL_INFO, " %s", nametypetrans->obj->datum.name); 1115 } else { 1116 cil_log(CIL_INFO, " %s", nametypetrans->obj_str); 1117 } 1118 1119 cil_log(CIL_INFO, " %s\n", nametypetrans->name_str); 1120 1121 if (nametypetrans->result != NULL) { 1122 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->result)->name); 1123 } else { 1124 cil_log(CIL_INFO, " %s", nametypetrans->result_str); 1125 } 1126 1127 return; 1128 } 1129 case CIL_RANGETRANSITION: { 1130 struct cil_rangetransition *rangetrans = node->data; 1131 cil_log(CIL_INFO, "RANGETRANSITION:"); 1132 1133 if (rangetrans->src != NULL) { 1134 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->src)->name); 1135 } else { 1136 cil_log(CIL_INFO, " %s", rangetrans->src_str); 1137 } 1138 1139 if (rangetrans->exec != NULL) { 1140 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->exec)->name); 1141 } else { 1142 cil_log(CIL_INFO, " %s", rangetrans->exec_str); 1143 } 1144 1145 if (rangetrans->obj != NULL) { 1146 cil_log(CIL_INFO, " %s", rangetrans->obj->datum.name); 1147 } else { 1148 cil_log(CIL_INFO, " %s", rangetrans->obj_str); 1149 } 1150 1151 if (rangetrans->range != NULL) { 1152 cil_log(CIL_INFO, " ("); 1153 cil_tree_print_levelrange(rangetrans->range); 1154 cil_log(CIL_INFO, " )"); 1155 } else { 1156 cil_log(CIL_INFO, " %s", rangetrans->range_str); 1157 } 1158 1159 cil_log(CIL_INFO, "\n"); 1160 return; 1161 } 1162 case CIL_AVRULE: { 1163 struct cil_avrule *rule = node->data; 1164 switch (rule->rule_kind) { 1165 case CIL_AVRULE_ALLOWED: 1166 cil_log(CIL_INFO, "ALLOW:"); 1167 break; 1168 case CIL_AVRULE_AUDITALLOW: 1169 cil_log(CIL_INFO, "AUDITALLOW:"); 1170 break; 1171 case CIL_AVRULE_DONTAUDIT: 1172 cil_log(CIL_INFO, "DONTAUDIT:"); 1173 break; 1174 case CIL_AVRULE_NEVERALLOW: 1175 cil_log(CIL_INFO, "NEVERALLOW:"); 1176 break; 1177 } 1178 1179 if (rule->src != NULL) { 1180 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->src)->name); 1181 } else { 1182 cil_log(CIL_INFO, " %s", rule->src_str); 1183 } 1184 1185 if (rule->tgt != NULL) { 1186 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->tgt)->name); 1187 } else { 1188 cil_log(CIL_INFO, " %s", rule->tgt_str); 1189 } 1190 1191 cil_tree_print_classperms_list(rule->perms.classperms); 1192 1193 cil_log(CIL_INFO, "\n"); 1194 1195 return; 1196 } 1197 case CIL_TYPE_RULE: { 1198 struct cil_type_rule *rule = node->data; 1199 switch (rule->rule_kind) { 1200 case CIL_TYPE_TRANSITION: 1201 cil_log(CIL_INFO, "TYPETRANSITION:"); 1202 break; 1203 case CIL_TYPE_MEMBER: 1204 cil_log(CIL_INFO, "TYPEMEMBER:"); 1205 break; 1206 case CIL_TYPE_CHANGE: 1207 cil_log(CIL_INFO, "TYPECHANGE:"); 1208 break; 1209 } 1210 1211 if (rule->src != NULL) { 1212 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->src)->name); 1213 } else { 1214 cil_log(CIL_INFO, " %s", rule->src_str); 1215 } 1216 1217 if (rule->tgt != NULL) { 1218 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->tgt)->name); 1219 } else { 1220 cil_log(CIL_INFO, " %s", rule->tgt_str); 1221 } 1222 1223 if (rule->obj != NULL) { 1224 cil_log(CIL_INFO, " %s", rule->obj->datum.name); 1225 } else { 1226 cil_log(CIL_INFO, " %s", rule->obj_str); 1227 } 1228 1229 if (rule->result != NULL) { 1230 cil_log(CIL_INFO, " %s\n", ((struct cil_symtab_datum *)rule->result)->name); 1231 } else { 1232 cil_log(CIL_INFO, " %s\n", rule->result_str); 1233 } 1234 1235 return; 1236 } 1237 case CIL_SENS: { 1238 struct cil_sens *sens = node->data; 1239 cil_log(CIL_INFO, "SENSITIVITY: %s\n", sens->datum.name); 1240 return; 1241 } 1242 case CIL_SENSALIAS: { 1243 struct cil_alias *alias = node->data; 1244 cil_log(CIL_INFO, "SENSITIVITYALIAS: %s\n", alias->datum.name); 1245 return; 1246 } 1247 case CIL_SENSALIASACTUAL: { 1248 struct cil_aliasactual *aliasactual = node->data; 1249 cil_log(CIL_INFO, "SENSITIVITYALIAS: alias: %s, sensitivity: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1250 1251 return; 1252 } 1253 case CIL_CAT: { 1254 struct cil_cat *cat = node->data; 1255 cil_log(CIL_INFO, "CATEGORY: %s\n", cat->datum.name); 1256 return; 1257 } 1258 case CIL_CATALIAS: { 1259 struct cil_alias *alias = node->data; 1260 cil_log(CIL_INFO, "CATEGORYALIAS: %s\n", alias->datum.name); 1261 return; 1262 } 1263 case CIL_CATALIASACTUAL: { 1264 struct cil_aliasactual *aliasactual = node->data; 1265 cil_log(CIL_INFO, "CATEGORYALIAS: alias %s, category: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1266 return; 1267 } 1268 case CIL_CATSET: { 1269 struct cil_catset *catset = node->data; 1270 1271 cil_log(CIL_INFO, "CATSET: %s ",catset->datum.name); 1272 1273 cil_tree_print_cats(catset->cats); 1274 1275 return; 1276 } 1277 case CIL_CATORDER: { 1278 struct cil_catorder *catorder = node->data; 1279 struct cil_list_item *cat; 1280 1281 if (catorder->cat_list_str == NULL) { 1282 cil_log(CIL_INFO, "CATORDER: ()\n"); 1283 return; 1284 } 1285 1286 cil_log(CIL_INFO, "CATORDER: ("); 1287 cil_list_for_each(cat, catorder->cat_list_str) { 1288 cil_log(CIL_INFO, " %s", (char*)cat->data); 1289 } 1290 cil_log(CIL_INFO, " )\n"); 1291 return; 1292 } 1293 case CIL_SENSCAT: { 1294 struct cil_senscat *senscat = node->data; 1295 1296 cil_log(CIL_INFO, "SENSCAT: sens:"); 1297 1298 if (senscat->sens_str != NULL) { 1299 cil_log(CIL_INFO, " %s ", senscat->sens_str); 1300 } else { 1301 cil_log(CIL_INFO, " [processed]"); 1302 } 1303 1304 cil_tree_print_cats(senscat->cats); 1305 1306 return; 1307 } 1308 case CIL_SENSITIVITYORDER: { 1309 struct cil_sensorder *sensorder = node->data; 1310 struct cil_list_item *sens; 1311 1312 cil_log(CIL_INFO, "SENSITIVITYORDER: ("); 1313 1314 if (sensorder->sens_list_str != NULL) { 1315 cil_list_for_each(sens, sensorder->sens_list_str) { 1316 if (sens->flavor == CIL_LIST) { 1317 struct cil_list_item *sub; 1318 cil_log(CIL_INFO, " ("); 1319 cil_list_for_each(sub, (struct cil_list*)sens->data) { 1320 cil_log(CIL_INFO, " %s", (char*)sub->data); 1321 } 1322 cil_log(CIL_INFO, " )"); 1323 } else { 1324 cil_log(CIL_INFO, " %s", (char*)sens->data); 1325 } 1326 } 1327 } 1328 1329 cil_log(CIL_INFO, " )\n"); 1330 return; 1331 } 1332 case CIL_LEVEL: { 1333 struct cil_level *level = node->data; 1334 cil_log(CIL_INFO, "LEVEL %s:", level->datum.name); 1335 cil_tree_print_level(level); 1336 cil_log(CIL_INFO, "\n"); 1337 return; 1338 } 1339 case CIL_LEVELRANGE: { 1340 struct cil_levelrange *lvlrange = node->data; 1341 cil_log(CIL_INFO, "LEVELRANGE %s:", lvlrange->datum.name); 1342 cil_tree_print_levelrange(lvlrange); 1343 cil_log(CIL_INFO, "\n"); 1344 return; 1345 } 1346 case CIL_CONSTRAIN: { 1347 struct cil_constrain *cons = node->data; 1348 cil_log(CIL_INFO, "CONSTRAIN: ("); 1349 cil_tree_print_constrain(cons); 1350 return; 1351 } 1352 case CIL_MLSCONSTRAIN: { 1353 struct cil_constrain *cons = node->data; 1354 cil_log(CIL_INFO, "MLSCONSTRAIN: ("); 1355 cil_tree_print_constrain(cons); 1356 return; 1357 } 1358 case CIL_VALIDATETRANS: { 1359 struct cil_validatetrans *vt = node->data; 1360 1361 cil_log(CIL_INFO, "(VALIDATETRANS "); 1362 1363 if (vt->class != NULL) { 1364 cil_log(CIL_INFO, "%s ", vt->class->datum.name); 1365 } else if (vt->class_str != NULL) { 1366 cil_log(CIL_INFO, "%s ", vt->class_str); 1367 } 1368 1369 cil_tree_print_expr(vt->datum_expr, vt->str_expr); 1370 1371 cil_log(CIL_INFO, ")\n"); 1372 return; 1373 } 1374 case CIL_MLSVALIDATETRANS: { 1375 struct cil_validatetrans *vt = node->data; 1376 1377 cil_log(CIL_INFO, "(MLSVALIDATETRANS "); 1378 1379 if (vt->class != NULL) { 1380 cil_log(CIL_INFO, "%s ", vt->class->datum.name); 1381 } else if (vt->class_str != NULL) { 1382 cil_log(CIL_INFO, "%s ", vt->class_str); 1383 } 1384 1385 cil_tree_print_expr(vt->datum_expr, vt->str_expr); 1386 1387 cil_log(CIL_INFO, ")\n"); 1388 return; 1389 } 1390 case CIL_CONTEXT: { 1391 struct cil_context *context = node->data; 1392 cil_log(CIL_INFO, "CONTEXT %s:", context->datum.name); 1393 cil_tree_print_context(context); 1394 cil_log(CIL_INFO, "\n"); 1395 return; 1396 } 1397 case CIL_FILECON: { 1398 struct cil_filecon *filecon = node->data; 1399 cil_log(CIL_INFO, "FILECON:"); 1400 cil_log(CIL_INFO, " %s %d", filecon->path_str, filecon->type); 1401 1402 if (filecon->context != NULL) { 1403 cil_tree_print_context(filecon->context); 1404 } else if (filecon->context_str != NULL) { 1405 cil_log(CIL_INFO, " %s", filecon->context_str); 1406 } 1407 1408 cil_log(CIL_INFO, "\n"); 1409 return; 1410 1411 } 1412 case CIL_PORTCON: { 1413 struct cil_portcon *portcon = node->data; 1414 cil_log(CIL_INFO, "PORTCON:"); 1415 if (portcon->proto == CIL_PROTOCOL_UDP) { 1416 cil_log(CIL_INFO, " udp"); 1417 } else if (portcon->proto == CIL_PROTOCOL_TCP) { 1418 cil_log(CIL_INFO, " tcp"); 1419 } else if (portcon->proto == CIL_PROTOCOL_DCCP) { 1420 cil_log(CIL_INFO, " dccp"); 1421 } 1422 cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high); 1423 1424 if (portcon->context != NULL) { 1425 cil_tree_print_context(portcon->context); 1426 } else if (portcon->context_str != NULL) { 1427 cil_log(CIL_INFO, " %s", portcon->context_str); 1428 } 1429 1430 cil_log(CIL_INFO, "\n"); 1431 return; 1432 } 1433 case CIL_NODECON: { 1434 struct cil_nodecon *nodecon = node->data; 1435 char buf[256]; 1436 1437 cil_log(CIL_INFO, "NODECON:"); 1438 1439 if (nodecon->addr) { 1440 inet_ntop(nodecon->addr->family, &nodecon->addr->ip, buf, 256); 1441 cil_log(CIL_INFO, " %s", buf); 1442 } else { 1443 cil_log(CIL_INFO, " %s", nodecon->addr_str); 1444 } 1445 1446 if (nodecon->mask) { 1447 inet_ntop(nodecon->mask->family, &nodecon->mask->ip, buf, 256); 1448 cil_log(CIL_INFO, " %s", buf); 1449 } else { 1450 cil_log(CIL_INFO, " %s", nodecon->mask_str); 1451 } 1452 1453 if (nodecon->context != NULL) { 1454 cil_tree_print_context(nodecon->context); 1455 } else if (nodecon->context_str != NULL) { 1456 cil_log(CIL_INFO, " %s", nodecon->context_str); 1457 } 1458 1459 cil_log(CIL_INFO, "\n"); 1460 return; 1461 } 1462 case CIL_GENFSCON: { 1463 struct cil_genfscon *genfscon = node->data; 1464 cil_log(CIL_INFO, "GENFSCON:"); 1465 cil_log(CIL_INFO, " %s %s", genfscon->fs_str, genfscon->path_str); 1466 1467 if (genfscon->context != NULL) { 1468 cil_tree_print_context(genfscon->context); 1469 } else if (genfscon->context_str != NULL) { 1470 cil_log(CIL_INFO, " %s", genfscon->context_str); 1471 } 1472 1473 cil_log(CIL_INFO, "\n"); 1474 return; 1475 } 1476 case CIL_NETIFCON: { 1477 struct cil_netifcon *netifcon = node->data; 1478 cil_log(CIL_INFO, "NETIFCON %s", netifcon->interface_str); 1479 1480 if (netifcon->if_context != NULL) { 1481 cil_tree_print_context(netifcon->if_context); 1482 } else if (netifcon->if_context_str != NULL) { 1483 cil_log(CIL_INFO, " %s", netifcon->if_context_str); 1484 } 1485 1486 if (netifcon->packet_context != NULL) { 1487 cil_tree_print_context(netifcon->packet_context); 1488 } else if (netifcon->packet_context_str != NULL) { 1489 cil_log(CIL_INFO, " %s", netifcon->packet_context_str); 1490 } 1491 1492 cil_log(CIL_INFO, "\n"); 1493 return; 1494 } 1495 case CIL_PIRQCON: { 1496 struct cil_pirqcon *pirqcon = node->data; 1497 1498 cil_log(CIL_INFO, "PIRQCON %d", pirqcon->pirq); 1499 if (pirqcon->context != NULL) { 1500 cil_tree_print_context(pirqcon->context); 1501 } else { 1502 cil_log(CIL_INFO, " %s", pirqcon->context_str); 1503 } 1504 1505 cil_log(CIL_INFO, "\n"); 1506 return; 1507 } 1508 case CIL_IOMEMCON: { 1509 struct cil_iomemcon *iomemcon = node->data; 1510 1511 cil_log(CIL_INFO, "IOMEMCON ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high); 1512 if (iomemcon->context != NULL) { 1513 cil_tree_print_context(iomemcon->context); 1514 } else { 1515 cil_log(CIL_INFO, " %s", iomemcon->context_str); 1516 } 1517 1518 cil_log(CIL_INFO, "\n"); 1519 return; 1520 } 1521 case CIL_IOPORTCON: { 1522 struct cil_ioportcon *ioportcon = node->data; 1523 1524 cil_log(CIL_INFO, "IOPORTCON ( %d %d )", ioportcon->ioport_low, ioportcon->ioport_high); 1525 if (ioportcon->context != NULL) { 1526 cil_tree_print_context(ioportcon->context); 1527 } else { 1528 cil_log(CIL_INFO, " %s", ioportcon->context_str); 1529 } 1530 1531 cil_log(CIL_INFO, "\n"); 1532 return; 1533 } 1534 case CIL_PCIDEVICECON: { 1535 struct cil_pcidevicecon *pcidevicecon = node->data; 1536 1537 cil_log(CIL_INFO, "PCIDEVICECON %d", pcidevicecon->dev); 1538 if (pcidevicecon->context != NULL) { 1539 cil_tree_print_context(pcidevicecon->context); 1540 } else { 1541 cil_log(CIL_INFO, " %s", pcidevicecon->context_str); 1542 } 1543 1544 cil_log(CIL_INFO, "\n"); 1545 return; 1546 } 1547 case CIL_DEVICETREECON: { 1548 struct cil_devicetreecon *devicetreecon = node->data; 1549 1550 cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path); 1551 if (devicetreecon->context != NULL) { 1552 cil_tree_print_context(devicetreecon->context); 1553 } else { 1554 cil_log(CIL_INFO, " %s", devicetreecon->context_str); 1555 } 1556 1557 cil_log(CIL_INFO, "\n"); 1558 return; 1559 } 1560 case CIL_FSUSE: { 1561 struct cil_fsuse *fsuse = node->data; 1562 cil_log(CIL_INFO, "FSUSE: "); 1563 1564 if (fsuse->type == CIL_FSUSE_XATTR) { 1565 cil_log(CIL_INFO, "xattr "); 1566 } else if (fsuse->type == CIL_FSUSE_TASK) { 1567 cil_log(CIL_INFO, "task "); 1568 } else if (fsuse->type == CIL_FSUSE_TRANS) { 1569 cil_log(CIL_INFO, "trans "); 1570 } else { 1571 cil_log(CIL_INFO, "unknown "); 1572 } 1573 1574 cil_log(CIL_INFO, "%s ", fsuse->fs_str); 1575 1576 if (fsuse->context != NULL) { 1577 cil_tree_print_context(fsuse->context); 1578 } else { 1579 cil_log(CIL_INFO, " %s", fsuse->context_str); 1580 } 1581 1582 cil_log(CIL_INFO, "\n"); 1583 return; 1584 } 1585 case CIL_SID: { 1586 struct cil_sid *sid = node->data; 1587 cil_log(CIL_INFO, "SID: %s\n", sid->datum.name); 1588 return; 1589 } 1590 case CIL_SIDCONTEXT: { 1591 struct cil_sidcontext *sidcon = node->data; 1592 cil_log(CIL_INFO, "SIDCONTEXT: %s", sidcon->sid_str); 1593 1594 if (sidcon->context != NULL) { 1595 cil_tree_print_context(sidcon->context); 1596 } else { 1597 cil_log(CIL_INFO, " %s", sidcon->context_str); 1598 } 1599 1600 cil_log(CIL_INFO, "\n"); 1601 return; 1602 } 1603 case CIL_SIDORDER: { 1604 struct cil_sidorder *sidorder = node->data; 1605 struct cil_list_item *sid; 1606 1607 if (sidorder->sid_list_str == NULL) { 1608 cil_log(CIL_INFO, "SIDORDER: ()\n"); 1609 return; 1610 } 1611 1612 cil_log(CIL_INFO, "SIDORDER: ("); 1613 cil_list_for_each(sid, sidorder->sid_list_str) { 1614 cil_log(CIL_INFO, " %s", (char*)sid->data); 1615 } 1616 cil_log(CIL_INFO, " )\n"); 1617 return; 1618 } 1619 case CIL_POLICYCAP: { 1620 struct cil_policycap *polcap = node->data; 1621 cil_log(CIL_INFO, "POLICYCAP: %s\n", polcap->datum.name); 1622 return; 1623 } 1624 case CIL_MACRO: { 1625 struct cil_macro *macro = node->data; 1626 cil_log(CIL_INFO, "MACRO %s:", macro->datum.name); 1627 1628 if (macro->params != NULL && macro->params->head != NULL) { 1629 struct cil_list_item *curr_param; 1630 cil_log(CIL_INFO, " parameters: ("); 1631 cil_list_for_each(curr_param, macro->params) { 1632 cil_log(CIL_INFO, " flavor: %d, string: %s;", ((struct cil_param*)curr_param->data)->flavor, ((struct cil_param*)curr_param->data)->str); 1633 1634 } 1635 cil_log(CIL_INFO, " )"); 1636 } 1637 cil_log(CIL_INFO, "\n"); 1638 1639 return; 1640 } 1641 case CIL_CALL: { 1642 struct cil_call *call = node->data; 1643 cil_log(CIL_INFO, "CALL: macro name:"); 1644 1645 if (call->macro != NULL) { 1646 cil_log(CIL_INFO, " %s", call->macro->datum.name); 1647 } else { 1648 cil_log(CIL_INFO, " %s", call->macro_str); 1649 } 1650 1651 if (call->args != NULL) { 1652 cil_log(CIL_INFO, ", args: ( "); 1653 struct cil_list_item *item; 1654 cil_list_for_each(item, call->args) { 1655 struct cil_symtab_datum *datum = ((struct cil_args*)item->data)->arg; 1656 if (datum != NULL) { 1657 if (datum->nodes != NULL && datum->nodes->head != NULL) { 1658 cil_tree_print_node((struct cil_tree_node*)datum->nodes->head->data); 1659 } 1660 } else if (((struct cil_args*)item->data)->arg_str != NULL) { 1661 switch (item->flavor) { 1662 case CIL_TYPE: cil_log(CIL_INFO, "type:"); break; 1663 case CIL_USER: cil_log(CIL_INFO, "user:"); break; 1664 case CIL_ROLE: cil_log(CIL_INFO, "role:"); break; 1665 case CIL_SENS: cil_log(CIL_INFO, "sensitivity:"); break; 1666 case CIL_CAT: cil_log(CIL_INFO, "category:"); break; 1667 case CIL_CATSET: cil_log(CIL_INFO, "categoryset:"); break; 1668 case CIL_LEVEL: cil_log(CIL_INFO, "level:"); break; 1669 case CIL_CLASS: cil_log(CIL_INFO, "class:"); break; 1670 default: break; 1671 } 1672 cil_log(CIL_INFO, "%s ", ((struct cil_args*)item->data)->arg_str); 1673 } 1674 } 1675 cil_log(CIL_INFO, ")"); 1676 } 1677 1678 cil_log(CIL_INFO, "\n"); 1679 return; 1680 } 1681 case CIL_OPTIONAL: { 1682 struct cil_optional *optional = node->data; 1683 cil_log(CIL_INFO, "OPTIONAL: %s\n", optional->datum.name); 1684 return; 1685 } 1686 case CIL_IPADDR: { 1687 struct cil_ipaddr *ipaddr = node->data; 1688 char buf[256]; 1689 1690 inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256); 1691 cil_log(CIL_INFO, "IPADDR %s: %s\n", ipaddr->datum.name, buf); 1692 1693 break; 1694 } 1695 default : { 1696 cil_log(CIL_INFO, "CIL FLAVOR: %d\n", node->flavor); 1697 return; 1698 } 1699 } 1700 } 1701 } 1702 1703 void cil_tree_print(struct cil_tree_node *tree, uint32_t depth) 1704 { 1705 struct cil_tree_node *current = NULL; 1706 current = tree; 1707 uint32_t x = 0; 1708 1709 if (current != NULL) { 1710 if (current->cl_head == NULL) { 1711 if (current->flavor == CIL_NODE) { 1712 if (current->parent->cl_head == current) { 1713 cil_log(CIL_INFO, "%s", (char*)current->data); 1714 } else { 1715 cil_log(CIL_INFO, " %s", (char*)current->data); 1716 } 1717 } else if (current->flavor != CIL_PERM) { 1718 for (x = 0; x<depth; x++) { 1719 cil_log(CIL_INFO, "\t"); 1720 } 1721 cil_tree_print_node(current); 1722 } 1723 } else { 1724 if (current->parent != NULL) { 1725 cil_log(CIL_INFO, "\n"); 1726 for (x = 0; x<depth; x++) { 1727 cil_log(CIL_INFO, "\t"); 1728 } 1729 cil_log(CIL_INFO, "("); 1730 1731 if (current->flavor != CIL_NODE) { 1732 cil_tree_print_node(current); 1733 } 1734 } 1735 cil_tree_print(current->cl_head, depth + 1); 1736 } 1737 1738 if (current->next == NULL) { 1739 if ((current->parent != NULL) && (current->parent->cl_tail == current) && (current->parent->parent != NULL)) { 1740 if (current->flavor == CIL_PERM) { 1741 cil_log(CIL_INFO, ")\n"); 1742 } else if (current->flavor != CIL_NODE) { 1743 for (x = 0; x<depth-1; x++) { 1744 cil_log(CIL_INFO, "\t"); 1745 } 1746 cil_log(CIL_INFO, ")\n"); 1747 } else { 1748 cil_log(CIL_INFO, ")"); 1749 } 1750 } 1751 1752 if ((current->parent != NULL) && (current->parent->parent == NULL)) 1753 cil_log(CIL_INFO, "\n\n"); 1754 } else { 1755 cil_tree_print(current->next, depth); 1756 } 1757 } else { 1758 cil_log(CIL_INFO, "Tree is NULL\n"); 1759 } 1760 } 1761