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 int rc; 507 508 cil_log(CIL_INFO, "("); 509 510 if (datum_expr != NULL) { 511 rc = cil_expr_to_string(datum_expr, &expr_str); 512 } else { 513 rc = cil_expr_to_string(str_expr, &expr_str); 514 } 515 if (rc != SEPOL_OK) { 516 cil_log(CIL_INFO, "ERROR)"); 517 return; 518 } 519 cil_log(CIL_INFO, "%s)", expr_str); 520 free(expr_str); 521 } 522 523 void cil_tree_print_perms_list(struct cil_tree_node *current_perm) 524 { 525 while (current_perm != NULL) { 526 if (current_perm->flavor == CIL_PERM) { 527 cil_log(CIL_INFO, " %s", ((struct cil_perm *)current_perm->data)->datum.name); 528 } else if (current_perm->flavor == CIL_MAP_PERM) { 529 cil_log(CIL_INFO, " %s", ((struct cil_perm*)current_perm->data)->datum.name); 530 } else { 531 cil_log(CIL_INFO, "\n\n perms list contained unexpected data type: %d\n", current_perm->flavor); 532 break; 533 } 534 current_perm = current_perm->next; 535 } 536 } 537 538 void cil_tree_print_cats(struct cil_cats *cats) 539 { 540 cil_tree_print_expr(cats->datum_expr, cats->str_expr); 541 } 542 543 void cil_tree_print_perm_strs(struct cil_list *perm_strs) 544 { 545 struct cil_list_item *curr; 546 547 if (perm_strs == NULL) { 548 return; 549 } 550 551 cil_log(CIL_INFO, " ("); 552 553 cil_list_for_each(curr, perm_strs) { 554 cil_log(CIL_INFO, " %s", (char*)curr->data); 555 } 556 557 cil_log(CIL_INFO, " )"); 558 } 559 560 561 void cil_tree_print_classperms(struct cil_classperms *cp) 562 { 563 if (cp == NULL) { 564 return; 565 } 566 567 cil_log(CIL_INFO, " class: %s", cp->class_str); 568 cil_log(CIL_INFO, ", perm_strs:"); 569 cil_tree_print_perm_strs(cp->perm_strs); 570 } 571 572 void cil_tree_print_classperms_set(struct cil_classperms_set *cp_set) 573 { 574 if (cp_set == NULL) { 575 return; 576 } 577 578 cil_log(CIL_INFO, " %s", cp_set->set_str); 579 } 580 581 void cil_tree_print_classperms_list(struct cil_list *cp_list) 582 { 583 struct cil_list_item *i; 584 585 if (cp_list == NULL) { 586 return; 587 } 588 589 cil_list_for_each(i, cp_list) { 590 if (i->flavor == CIL_CLASSPERMS) { 591 cil_tree_print_classperms(i->data); 592 } else { 593 cil_tree_print_classperms_set(i->data); 594 } 595 } 596 } 597 598 void cil_tree_print_level(struct cil_level *level) 599 { 600 if (level->sens != NULL) { 601 cil_log(CIL_INFO, " %s", level->sens->datum.name); 602 } else if (level->sens_str != NULL) { 603 cil_log(CIL_INFO, " %s", level->sens_str); 604 } 605 606 cil_tree_print_cats(level->cats); 607 608 return; 609 } 610 611 void cil_tree_print_levelrange(struct cil_levelrange *lvlrange) 612 { 613 cil_log(CIL_INFO, " ("); 614 if (lvlrange->low != NULL) { 615 cil_log(CIL_INFO, " ("); 616 cil_tree_print_level(lvlrange->low); 617 cil_log(CIL_INFO, " )"); 618 } else if (lvlrange->low_str != NULL) { 619 cil_log(CIL_INFO, " %s", lvlrange->low_str); 620 } 621 622 if (lvlrange->high != NULL) { 623 cil_log(CIL_INFO, " ("); 624 cil_tree_print_level(lvlrange->high); 625 cil_log(CIL_INFO, " )"); 626 } else if (lvlrange->high_str != NULL) { 627 cil_log(CIL_INFO, " %s", lvlrange->high_str); 628 } 629 cil_log(CIL_INFO, " )"); 630 } 631 632 void cil_tree_print_context(struct cil_context *context) 633 { 634 cil_log(CIL_INFO, " ("); 635 if (context->user != NULL) { 636 cil_log(CIL_INFO, " %s", context->user->datum.name); 637 } else if (context->user_str != NULL) { 638 cil_log(CIL_INFO, " %s", context->user_str); 639 } 640 641 if (context->role != NULL) { 642 cil_log(CIL_INFO, " %s", context->role->datum.name); 643 } else if (context->role_str != NULL) { 644 cil_log(CIL_INFO, " %s", context->role_str); 645 } 646 647 if (context->type != NULL) { 648 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)context->type)->name); 649 } else if (context->type_str != NULL) { 650 cil_log(CIL_INFO, " %s", context->type_str); 651 } 652 653 if (context->range != NULL) { 654 cil_tree_print_levelrange(context->range); 655 } else if (context->range_str != NULL) { 656 cil_log(CIL_INFO, " %s", context->range_str); 657 } 658 659 cil_log(CIL_INFO, " )"); 660 661 return; 662 } 663 664 void cil_tree_print_constrain(struct cil_constrain *cons) 665 { 666 cil_tree_print_classperms_list(cons->classperms); 667 668 cil_tree_print_expr(cons->datum_expr, cons->str_expr); 669 670 cil_log(CIL_INFO, "\n"); 671 } 672 673 void cil_tree_print_node(struct cil_tree_node *node) 674 { 675 if (node->data == NULL) { 676 cil_log(CIL_INFO, "FLAVOR: %d", node->flavor); 677 return; 678 } else { 679 switch( node->flavor ) { 680 case CIL_BLOCK: { 681 struct cil_block *block = node->data; 682 cil_log(CIL_INFO, "BLOCK: %s\n", block->datum.name); 683 return; 684 } 685 case CIL_BLOCKINHERIT: { 686 struct cil_blockinherit *inherit = node->data; 687 cil_log(CIL_INFO, "BLOCKINHERIT: %s\n", inherit->block_str); 688 return; 689 } 690 case CIL_BLOCKABSTRACT: { 691 struct cil_blockabstract *abstract = node->data; 692 cil_log(CIL_INFO, "BLOCKABSTRACT: %s\n", abstract->block_str); 693 return; 694 } 695 case CIL_IN: { 696 struct cil_in *in = node->data; 697 cil_log(CIL_INFO, "IN: %s\n", in->block_str); 698 return; 699 } 700 case CIL_USER: { 701 struct cil_user *user = node->data; 702 cil_log(CIL_INFO, "USER: %s\n", user->datum.name); 703 return; 704 } 705 case CIL_TYPE: { 706 struct cil_type *type = node->data; 707 cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name); 708 return; 709 } 710 case CIL_EXPANDTYPEATTRIBUTE: { 711 struct cil_expandtypeattribute *attr = node->data; 712 713 fprintf(stderr, "%s %u\n", __func__, __LINE__); 714 cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE "); 715 cil_tree_print_expr(attr->attr_datums, attr->attr_strs); 716 cil_log(CIL_INFO, "%s)\n",attr->expand ? 717 CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE); 718 719 return; 720 } 721 case CIL_TYPEATTRIBUTESET: { 722 struct cil_typeattributeset *attr = node->data; 723 724 cil_log(CIL_INFO, "(TYPEATTRIBUTESET %s ", attr->attr_str); 725 726 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 727 728 cil_log(CIL_INFO, "\n"); 729 return; 730 } 731 case CIL_TYPEATTRIBUTE: { 732 struct cil_typeattribute *attr = node->data; 733 cil_log(CIL_INFO, "TYPEATTRIBUTE: %s\n", attr->datum.name); 734 return; 735 } 736 case CIL_ROLE: { 737 struct cil_role *role = node->data; 738 cil_log(CIL_INFO, "ROLE: %s\n", role->datum.name); 739 return; 740 } 741 case CIL_USERROLE: { 742 struct cil_userrole *userrole = node->data; 743 cil_log(CIL_INFO, "USERROLE:"); 744 struct cil_symtab_datum *datum = NULL; 745 746 if (userrole->user != NULL) { 747 datum = userrole->user; 748 cil_log(CIL_INFO, " %s", datum->name); 749 } else if (userrole->user_str != NULL) { 750 cil_log(CIL_INFO, " %s", userrole->user_str); 751 } 752 753 if (userrole->role != NULL) { 754 datum = userrole->role; 755 cil_log(CIL_INFO, " %s", datum->name); 756 } else if (userrole->role_str != NULL) { 757 cil_log(CIL_INFO, " %s", userrole->role_str); 758 } 759 760 cil_log(CIL_INFO, "\n"); 761 return; 762 } 763 case CIL_USERLEVEL: { 764 struct cil_userlevel *usrlvl = node->data; 765 cil_log(CIL_INFO, "USERLEVEL:"); 766 767 if (usrlvl->user_str != NULL) { 768 cil_log(CIL_INFO, " %s", usrlvl->user_str); 769 } 770 771 if (usrlvl->level != NULL) { 772 cil_log(CIL_INFO, " ("); 773 cil_tree_print_level(usrlvl->level); 774 cil_log(CIL_INFO, " )"); 775 } else if (usrlvl->level_str != NULL) { 776 cil_log(CIL_INFO, " %s", usrlvl->level_str); 777 } 778 779 cil_log(CIL_INFO, "\n"); 780 return; 781 } 782 case CIL_USERRANGE: { 783 struct cil_userrange *userrange = node->data; 784 cil_log(CIL_INFO, "USERRANGE:"); 785 786 if (userrange->user_str != NULL) { 787 cil_log(CIL_INFO, " %s", userrange->user_str); 788 } 789 790 if (userrange->range != NULL) { 791 cil_log(CIL_INFO, " ("); 792 cil_tree_print_levelrange(userrange->range); 793 cil_log(CIL_INFO, " )"); 794 } else if (userrange->range_str != NULL) { 795 cil_log(CIL_INFO, " %s", userrange->range_str); 796 } 797 798 cil_log(CIL_INFO, "\n"); 799 return; 800 } 801 case CIL_USERBOUNDS: { 802 struct cil_bounds *bnds = node->data; 803 cil_log(CIL_INFO, "USERBOUNDS: user: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 804 return; 805 } 806 case CIL_ROLETYPE: { 807 struct cil_roletype *roletype = node->data; 808 struct cil_symtab_datum *datum = NULL; 809 cil_log(CIL_INFO, "ROLETYPE:"); 810 811 if (roletype->role != NULL) { 812 datum = roletype->role; 813 cil_log(CIL_INFO, " %s", datum->name); 814 } else if (roletype->role_str != NULL) { 815 cil_log(CIL_INFO, " %s", roletype->role_str); 816 } 817 818 if (roletype->type != NULL) { 819 datum = roletype->type; 820 cil_log(CIL_INFO, " %s", datum->name); 821 } else if (roletype->type_str != NULL) { 822 cil_log(CIL_INFO, " %s", roletype->type_str); 823 } 824 825 cil_log(CIL_INFO, "\n"); 826 return; 827 } 828 case CIL_ROLETRANSITION: { 829 struct cil_roletransition *roletrans = node->data; 830 cil_log(CIL_INFO, "ROLETRANSITION:"); 831 832 if (roletrans->src != NULL) { 833 cil_log(CIL_INFO, " %s", roletrans->src->datum.name); 834 } else { 835 cil_log(CIL_INFO, " %s", roletrans->src_str); 836 } 837 838 if (roletrans->tgt != NULL) { 839 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)roletrans->tgt)->name); 840 } else { 841 cil_log(CIL_INFO, " %s", roletrans->tgt_str); 842 } 843 844 if (roletrans->obj != NULL) { 845 cil_log(CIL_INFO, " %s", roletrans->obj->datum.name); 846 } else { 847 cil_log(CIL_INFO, " %s", roletrans->obj_str); 848 } 849 850 if (roletrans->result != NULL) { 851 cil_log(CIL_INFO, " %s\n", roletrans->result->datum.name); 852 } else { 853 cil_log(CIL_INFO, " %s\n", roletrans->result_str); 854 } 855 856 return; 857 } 858 case CIL_ROLEALLOW: { 859 struct cil_roleallow *roleallow = node->data; 860 cil_log(CIL_INFO, "ROLEALLOW:"); 861 862 if (roleallow->src != NULL) { 863 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->src)->name); 864 } else { 865 cil_log(CIL_INFO, " %s", roleallow->src_str); 866 } 867 868 if (roleallow->tgt != NULL) { 869 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->tgt)->name); 870 } else { 871 cil_log(CIL_INFO, " %s", roleallow->tgt_str); 872 } 873 874 cil_log(CIL_INFO, "\n"); 875 return; 876 } 877 case CIL_ROLEATTRIBUTESET: { 878 struct cil_roleattributeset *attr = node->data; 879 880 cil_log(CIL_INFO, "(ROLEATTRIBUTESET %s ", attr->attr_str); 881 882 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 883 884 cil_log(CIL_INFO, "\n"); 885 return; 886 } 887 case CIL_ROLEATTRIBUTE: { 888 struct cil_roleattribute *attr = node->data; 889 cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name); 890 return; 891 } 892 case CIL_USERATTRIBUTESET: { 893 struct cil_userattributeset *attr = node->data; 894 895 cil_log(CIL_INFO, "(USERATTRIBUTESET %s ", attr->attr_str); 896 897 cil_tree_print_expr(attr->datum_expr, attr->str_expr); 898 899 cil_log(CIL_INFO, "\n"); 900 return; 901 } 902 case CIL_USERATTRIBUTE: { 903 struct cil_userattribute *attr = node->data; 904 cil_log(CIL_INFO, "USERATTRIBUTE: %s\n", attr->datum.name); 905 return; 906 } 907 case CIL_ROLEBOUNDS: { 908 struct cil_bounds *bnds = node->data; 909 cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 910 return; 911 } 912 case CIL_CLASS: { 913 struct cil_class *cls = node->data; 914 cil_log(CIL_INFO, "CLASS: %s ", cls->datum.name); 915 916 if (cls->common != NULL) { 917 cil_log(CIL_INFO, "inherits: %s ", cls->common->datum.name); 918 } 919 cil_log(CIL_INFO, "("); 920 921 cil_tree_print_perms_list(node->cl_head); 922 923 cil_log(CIL_INFO, " )"); 924 return; 925 } 926 case CIL_CLASSORDER: { 927 struct cil_classorder *classorder = node->data; 928 struct cil_list_item *class; 929 930 if (classorder->class_list_str == NULL) { 931 cil_log(CIL_INFO, "CLASSORDER: ()\n"); 932 return; 933 } 934 935 cil_log(CIL_INFO, "CLASSORDER: ("); 936 cil_list_for_each(class, classorder->class_list_str) { 937 cil_log(CIL_INFO, " %s", (char*)class->data); 938 } 939 cil_log(CIL_INFO, " )\n"); 940 return; 941 } 942 case CIL_COMMON: { 943 struct cil_class *common = node->data; 944 cil_log(CIL_INFO, "COMMON: %s (", common->datum.name); 945 946 cil_tree_print_perms_list(node->cl_head); 947 948 cil_log(CIL_INFO, " )"); 949 return; 950 } 951 case CIL_CLASSCOMMON: { 952 struct cil_classcommon *clscom = node->data; 953 954 cil_log(CIL_INFO, "CLASSCOMMON: class: %s, common: %s\n", clscom->class_str, clscom->common_str); 955 956 return; 957 } 958 case CIL_CLASSPERMISSION: { 959 struct cil_classpermission *cp = node->data; 960 961 cil_log(CIL_INFO, "CLASSPERMISSION: %s", cp->datum.name); 962 963 cil_log(CIL_INFO, "\n"); 964 965 return; 966 } 967 case CIL_CLASSPERMISSIONSET: { 968 struct cil_classpermissionset *cps = node->data; 969 970 cil_log(CIL_INFO, "CLASSPERMISSIONSET: %s", cps->set_str); 971 972 cil_tree_print_classperms_list(cps->classperms); 973 974 cil_log(CIL_INFO, "\n"); 975 976 return; 977 } 978 case CIL_MAP_CLASS: { 979 struct cil_class *cm = node->data; 980 cil_log(CIL_INFO, "MAP_CLASS: %s", cm->datum.name); 981 982 cil_log(CIL_INFO, " ("); 983 cil_tree_print_perms_list(node->cl_head); 984 cil_log(CIL_INFO, " )\n"); 985 986 return; 987 } 988 case CIL_MAP_PERM: { 989 struct cil_perm *cmp = node->data; 990 991 cil_log(CIL_INFO, "MAP_PERM: %s", cmp->datum.name); 992 993 if (cmp->classperms == NULL) { 994 cil_log(CIL_INFO, " perms: ()"); 995 return; 996 } 997 998 cil_log(CIL_INFO, " kernel class perms: ("); 999 1000 cil_tree_print_classperms_list(cmp->classperms); 1001 1002 cil_log(CIL_INFO, " )\n"); 1003 1004 return; 1005 } 1006 case CIL_CLASSMAPPING: { 1007 struct cil_classmapping *mapping = node->data; 1008 1009 cil_log(CIL_INFO, "CLASSMAPPING: map class: %s, map perm: %s,", mapping->map_class_str, mapping->map_perm_str); 1010 1011 cil_log(CIL_INFO, " ("); 1012 1013 cil_tree_print_classperms_list(mapping->classperms); 1014 1015 cil_log(CIL_INFO, " )\n"); 1016 return; 1017 } 1018 case CIL_BOOL: { 1019 struct cil_bool *boolean = node->data; 1020 cil_log(CIL_INFO, "BOOL: %s, value: %d\n", boolean->datum.name, boolean->value); 1021 return; 1022 } 1023 case CIL_TUNABLE: { 1024 struct cil_tunable *tunable = node->data; 1025 cil_log(CIL_INFO, "TUNABLE: %s, value: %d\n", tunable->datum.name, tunable->value); 1026 return; 1027 } 1028 case CIL_BOOLEANIF: { 1029 struct cil_booleanif *bif = node->data; 1030 1031 cil_log(CIL_INFO, "(BOOLEANIF "); 1032 1033 cil_tree_print_expr(bif->datum_expr, bif->str_expr); 1034 1035 cil_log(CIL_INFO, " )\n"); 1036 return; 1037 } 1038 case CIL_TUNABLEIF: { 1039 struct cil_tunableif *tif = node->data; 1040 1041 cil_log(CIL_INFO, "(TUNABLEIF "); 1042 1043 cil_tree_print_expr(tif->datum_expr, tif->str_expr); 1044 1045 cil_log(CIL_INFO, " )\n"); 1046 return; 1047 } 1048 case CIL_CONDBLOCK: { 1049 struct cil_condblock *cb = node->data; 1050 if (cb->flavor == CIL_CONDTRUE) { 1051 cil_log(CIL_INFO, "true\n"); 1052 } else if (cb->flavor == CIL_CONDFALSE) { 1053 cil_log(CIL_INFO, "false\n"); 1054 } 1055 return; 1056 } 1057 case CIL_ALL: 1058 cil_log(CIL_INFO, "all"); 1059 return; 1060 case CIL_AND: 1061 cil_log(CIL_INFO, "&&"); 1062 return; 1063 case CIL_OR: 1064 cil_log(CIL_INFO, "|| "); 1065 return; 1066 case CIL_NOT: 1067 cil_log(CIL_INFO, "!"); 1068 return; 1069 case CIL_EQ: 1070 cil_log(CIL_INFO, "=="); 1071 return; 1072 case CIL_NEQ: 1073 cil_log(CIL_INFO, "!="); 1074 return; 1075 case CIL_TYPEALIAS: { 1076 struct cil_alias *alias = node->data; 1077 cil_log(CIL_INFO, "TYPEALIAS: %s\n", alias->datum.name); 1078 return; 1079 } 1080 case CIL_TYPEALIASACTUAL: { 1081 struct cil_aliasactual *aliasactual = node->data; 1082 cil_log(CIL_INFO, "TYPEALIASACTUAL: type: %s, alias: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1083 return; 1084 } 1085 case CIL_TYPEBOUNDS: { 1086 struct cil_bounds *bnds = node->data; 1087 cil_log(CIL_INFO, "TYPEBOUNDS: type: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); 1088 return; 1089 } 1090 case CIL_TYPEPERMISSIVE: { 1091 struct cil_typepermissive *typeperm = node->data; 1092 1093 if (typeperm->type != NULL) { 1094 cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", ((struct cil_symtab_datum *)typeperm->type)->name); 1095 } else { 1096 cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", typeperm->type_str); 1097 } 1098 1099 return; 1100 } 1101 case CIL_NAMETYPETRANSITION: { 1102 struct cil_nametypetransition *nametypetrans = node->data; 1103 cil_log(CIL_INFO, "TYPETRANSITION:"); 1104 1105 if (nametypetrans->src != NULL) { 1106 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->src)->name); 1107 } else { 1108 cil_log(CIL_INFO, " %s", nametypetrans->src_str); 1109 } 1110 1111 if (nametypetrans->tgt != NULL) { 1112 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->tgt)->name); 1113 } else { 1114 cil_log(CIL_INFO, " %s", nametypetrans->tgt_str); 1115 } 1116 1117 if (nametypetrans->obj != NULL) { 1118 cil_log(CIL_INFO, " %s", nametypetrans->obj->datum.name); 1119 } else { 1120 cil_log(CIL_INFO, " %s", nametypetrans->obj_str); 1121 } 1122 1123 cil_log(CIL_INFO, " %s\n", nametypetrans->name_str); 1124 1125 if (nametypetrans->result != NULL) { 1126 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->result)->name); 1127 } else { 1128 cil_log(CIL_INFO, " %s", nametypetrans->result_str); 1129 } 1130 1131 return; 1132 } 1133 case CIL_RANGETRANSITION: { 1134 struct cil_rangetransition *rangetrans = node->data; 1135 cil_log(CIL_INFO, "RANGETRANSITION:"); 1136 1137 if (rangetrans->src != NULL) { 1138 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->src)->name); 1139 } else { 1140 cil_log(CIL_INFO, " %s", rangetrans->src_str); 1141 } 1142 1143 if (rangetrans->exec != NULL) { 1144 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->exec)->name); 1145 } else { 1146 cil_log(CIL_INFO, " %s", rangetrans->exec_str); 1147 } 1148 1149 if (rangetrans->obj != NULL) { 1150 cil_log(CIL_INFO, " %s", rangetrans->obj->datum.name); 1151 } else { 1152 cil_log(CIL_INFO, " %s", rangetrans->obj_str); 1153 } 1154 1155 if (rangetrans->range != NULL) { 1156 cil_log(CIL_INFO, " ("); 1157 cil_tree_print_levelrange(rangetrans->range); 1158 cil_log(CIL_INFO, " )"); 1159 } else { 1160 cil_log(CIL_INFO, " %s", rangetrans->range_str); 1161 } 1162 1163 cil_log(CIL_INFO, "\n"); 1164 return; 1165 } 1166 case CIL_AVRULE: { 1167 struct cil_avrule *rule = node->data; 1168 switch (rule->rule_kind) { 1169 case CIL_AVRULE_ALLOWED: 1170 cil_log(CIL_INFO, "ALLOW:"); 1171 break; 1172 case CIL_AVRULE_AUDITALLOW: 1173 cil_log(CIL_INFO, "AUDITALLOW:"); 1174 break; 1175 case CIL_AVRULE_DONTAUDIT: 1176 cil_log(CIL_INFO, "DONTAUDIT:"); 1177 break; 1178 case CIL_AVRULE_NEVERALLOW: 1179 cil_log(CIL_INFO, "NEVERALLOW:"); 1180 break; 1181 } 1182 1183 if (rule->src != NULL) { 1184 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->src)->name); 1185 } else { 1186 cil_log(CIL_INFO, " %s", rule->src_str); 1187 } 1188 1189 if (rule->tgt != NULL) { 1190 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->tgt)->name); 1191 } else { 1192 cil_log(CIL_INFO, " %s", rule->tgt_str); 1193 } 1194 1195 cil_tree_print_classperms_list(rule->perms.classperms); 1196 1197 cil_log(CIL_INFO, "\n"); 1198 1199 return; 1200 } 1201 case CIL_TYPE_RULE: { 1202 struct cil_type_rule *rule = node->data; 1203 switch (rule->rule_kind) { 1204 case CIL_TYPE_TRANSITION: 1205 cil_log(CIL_INFO, "TYPETRANSITION:"); 1206 break; 1207 case CIL_TYPE_MEMBER: 1208 cil_log(CIL_INFO, "TYPEMEMBER:"); 1209 break; 1210 case CIL_TYPE_CHANGE: 1211 cil_log(CIL_INFO, "TYPECHANGE:"); 1212 break; 1213 } 1214 1215 if (rule->src != NULL) { 1216 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->src)->name); 1217 } else { 1218 cil_log(CIL_INFO, " %s", rule->src_str); 1219 } 1220 1221 if (rule->tgt != NULL) { 1222 cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->tgt)->name); 1223 } else { 1224 cil_log(CIL_INFO, " %s", rule->tgt_str); 1225 } 1226 1227 if (rule->obj != NULL) { 1228 cil_log(CIL_INFO, " %s", rule->obj->datum.name); 1229 } else { 1230 cil_log(CIL_INFO, " %s", rule->obj_str); 1231 } 1232 1233 if (rule->result != NULL) { 1234 cil_log(CIL_INFO, " %s\n", ((struct cil_symtab_datum *)rule->result)->name); 1235 } else { 1236 cil_log(CIL_INFO, " %s\n", rule->result_str); 1237 } 1238 1239 return; 1240 } 1241 case CIL_SENS: { 1242 struct cil_sens *sens = node->data; 1243 cil_log(CIL_INFO, "SENSITIVITY: %s\n", sens->datum.name); 1244 return; 1245 } 1246 case CIL_SENSALIAS: { 1247 struct cil_alias *alias = node->data; 1248 cil_log(CIL_INFO, "SENSITIVITYALIAS: %s\n", alias->datum.name); 1249 return; 1250 } 1251 case CIL_SENSALIASACTUAL: { 1252 struct cil_aliasactual *aliasactual = node->data; 1253 cil_log(CIL_INFO, "SENSITIVITYALIAS: alias: %s, sensitivity: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1254 1255 return; 1256 } 1257 case CIL_CAT: { 1258 struct cil_cat *cat = node->data; 1259 cil_log(CIL_INFO, "CATEGORY: %s\n", cat->datum.name); 1260 return; 1261 } 1262 case CIL_CATALIAS: { 1263 struct cil_alias *alias = node->data; 1264 cil_log(CIL_INFO, "CATEGORYALIAS: %s\n", alias->datum.name); 1265 return; 1266 } 1267 case CIL_CATALIASACTUAL: { 1268 struct cil_aliasactual *aliasactual = node->data; 1269 cil_log(CIL_INFO, "CATEGORYALIAS: alias %s, category: %s\n", aliasactual->alias_str, aliasactual->actual_str); 1270 return; 1271 } 1272 case CIL_CATSET: { 1273 struct cil_catset *catset = node->data; 1274 1275 cil_log(CIL_INFO, "CATSET: %s ",catset->datum.name); 1276 1277 cil_tree_print_cats(catset->cats); 1278 1279 return; 1280 } 1281 case CIL_CATORDER: { 1282 struct cil_catorder *catorder = node->data; 1283 struct cil_list_item *cat; 1284 1285 if (catorder->cat_list_str == NULL) { 1286 cil_log(CIL_INFO, "CATORDER: ()\n"); 1287 return; 1288 } 1289 1290 cil_log(CIL_INFO, "CATORDER: ("); 1291 cil_list_for_each(cat, catorder->cat_list_str) { 1292 cil_log(CIL_INFO, " %s", (char*)cat->data); 1293 } 1294 cil_log(CIL_INFO, " )\n"); 1295 return; 1296 } 1297 case CIL_SENSCAT: { 1298 struct cil_senscat *senscat = node->data; 1299 1300 cil_log(CIL_INFO, "SENSCAT: sens:"); 1301 1302 if (senscat->sens_str != NULL) { 1303 cil_log(CIL_INFO, " %s ", senscat->sens_str); 1304 } else { 1305 cil_log(CIL_INFO, " [processed]"); 1306 } 1307 1308 cil_tree_print_cats(senscat->cats); 1309 1310 return; 1311 } 1312 case CIL_SENSITIVITYORDER: { 1313 struct cil_sensorder *sensorder = node->data; 1314 struct cil_list_item *sens; 1315 1316 cil_log(CIL_INFO, "SENSITIVITYORDER: ("); 1317 1318 if (sensorder->sens_list_str != NULL) { 1319 cil_list_for_each(sens, sensorder->sens_list_str) { 1320 if (sens->flavor == CIL_LIST) { 1321 struct cil_list_item *sub; 1322 cil_log(CIL_INFO, " ("); 1323 cil_list_for_each(sub, (struct cil_list*)sens->data) { 1324 cil_log(CIL_INFO, " %s", (char*)sub->data); 1325 } 1326 cil_log(CIL_INFO, " )"); 1327 } else { 1328 cil_log(CIL_INFO, " %s", (char*)sens->data); 1329 } 1330 } 1331 } 1332 1333 cil_log(CIL_INFO, " )\n"); 1334 return; 1335 } 1336 case CIL_LEVEL: { 1337 struct cil_level *level = node->data; 1338 cil_log(CIL_INFO, "LEVEL %s:", level->datum.name); 1339 cil_tree_print_level(level); 1340 cil_log(CIL_INFO, "\n"); 1341 return; 1342 } 1343 case CIL_LEVELRANGE: { 1344 struct cil_levelrange *lvlrange = node->data; 1345 cil_log(CIL_INFO, "LEVELRANGE %s:", lvlrange->datum.name); 1346 cil_tree_print_levelrange(lvlrange); 1347 cil_log(CIL_INFO, "\n"); 1348 return; 1349 } 1350 case CIL_CONSTRAIN: { 1351 struct cil_constrain *cons = node->data; 1352 cil_log(CIL_INFO, "CONSTRAIN: ("); 1353 cil_tree_print_constrain(cons); 1354 return; 1355 } 1356 case CIL_MLSCONSTRAIN: { 1357 struct cil_constrain *cons = node->data; 1358 cil_log(CIL_INFO, "MLSCONSTRAIN: ("); 1359 cil_tree_print_constrain(cons); 1360 return; 1361 } 1362 case CIL_VALIDATETRANS: { 1363 struct cil_validatetrans *vt = node->data; 1364 1365 cil_log(CIL_INFO, "(VALIDATETRANS "); 1366 1367 if (vt->class != NULL) { 1368 cil_log(CIL_INFO, "%s ", vt->class->datum.name); 1369 } else if (vt->class_str != NULL) { 1370 cil_log(CIL_INFO, "%s ", vt->class_str); 1371 } 1372 1373 cil_tree_print_expr(vt->datum_expr, vt->str_expr); 1374 1375 cil_log(CIL_INFO, ")\n"); 1376 return; 1377 } 1378 case CIL_MLSVALIDATETRANS: { 1379 struct cil_validatetrans *vt = node->data; 1380 1381 cil_log(CIL_INFO, "(MLSVALIDATETRANS "); 1382 1383 if (vt->class != NULL) { 1384 cil_log(CIL_INFO, "%s ", vt->class->datum.name); 1385 } else if (vt->class_str != NULL) { 1386 cil_log(CIL_INFO, "%s ", vt->class_str); 1387 } 1388 1389 cil_tree_print_expr(vt->datum_expr, vt->str_expr); 1390 1391 cil_log(CIL_INFO, ")\n"); 1392 return; 1393 } 1394 case CIL_CONTEXT: { 1395 struct cil_context *context = node->data; 1396 cil_log(CIL_INFO, "CONTEXT %s:", context->datum.name); 1397 cil_tree_print_context(context); 1398 cil_log(CIL_INFO, "\n"); 1399 return; 1400 } 1401 case CIL_FILECON: { 1402 struct cil_filecon *filecon = node->data; 1403 cil_log(CIL_INFO, "FILECON:"); 1404 cil_log(CIL_INFO, " %s %d", filecon->path_str, filecon->type); 1405 1406 if (filecon->context != NULL) { 1407 cil_tree_print_context(filecon->context); 1408 } else if (filecon->context_str != NULL) { 1409 cil_log(CIL_INFO, " %s", filecon->context_str); 1410 } 1411 1412 cil_log(CIL_INFO, "\n"); 1413 return; 1414 1415 } 1416 case CIL_IBPKEYCON: { 1417 struct cil_ibpkeycon *ibpkeycon = node->data; 1418 1419 cil_log(CIL_INFO, "IBPKEYCON: %s", ibpkeycon->subnet_prefix_str); 1420 cil_log(CIL_INFO, " (%d %d) ", ibpkeycon->pkey_low, ibpkeycon->pkey_high); 1421 1422 if (ibpkeycon->context) 1423 cil_tree_print_context(ibpkeycon->context); 1424 else if (ibpkeycon->context_str) 1425 cil_log(CIL_INFO, " %s", ibpkeycon->context_str); 1426 1427 cil_log(CIL_INFO, "\n"); 1428 return; 1429 } 1430 case CIL_PORTCON: { 1431 struct cil_portcon *portcon = node->data; 1432 cil_log(CIL_INFO, "PORTCON:"); 1433 if (portcon->proto == CIL_PROTOCOL_UDP) { 1434 cil_log(CIL_INFO, " udp"); 1435 } else if (portcon->proto == CIL_PROTOCOL_TCP) { 1436 cil_log(CIL_INFO, " tcp"); 1437 } else if (portcon->proto == CIL_PROTOCOL_DCCP) { 1438 cil_log(CIL_INFO, " dccp"); 1439 } else if (portcon->proto == CIL_PROTOCOL_SCTP) { 1440 cil_log(CIL_INFO, " sctp"); 1441 } 1442 cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high); 1443 1444 if (portcon->context != NULL) { 1445 cil_tree_print_context(portcon->context); 1446 } else if (portcon->context_str != NULL) { 1447 cil_log(CIL_INFO, " %s", portcon->context_str); 1448 } 1449 1450 cil_log(CIL_INFO, "\n"); 1451 return; 1452 } 1453 case CIL_NODECON: { 1454 struct cil_nodecon *nodecon = node->data; 1455 char buf[256]; 1456 1457 cil_log(CIL_INFO, "NODECON:"); 1458 1459 if (nodecon->addr) { 1460 inet_ntop(nodecon->addr->family, &nodecon->addr->ip, buf, 256); 1461 cil_log(CIL_INFO, " %s", buf); 1462 } else { 1463 cil_log(CIL_INFO, " %s", nodecon->addr_str); 1464 } 1465 1466 if (nodecon->mask) { 1467 inet_ntop(nodecon->mask->family, &nodecon->mask->ip, buf, 256); 1468 cil_log(CIL_INFO, " %s", buf); 1469 } else { 1470 cil_log(CIL_INFO, " %s", nodecon->mask_str); 1471 } 1472 1473 if (nodecon->context != NULL) { 1474 cil_tree_print_context(nodecon->context); 1475 } else if (nodecon->context_str != NULL) { 1476 cil_log(CIL_INFO, " %s", nodecon->context_str); 1477 } 1478 1479 cil_log(CIL_INFO, "\n"); 1480 return; 1481 } 1482 case CIL_GENFSCON: { 1483 struct cil_genfscon *genfscon = node->data; 1484 cil_log(CIL_INFO, "GENFSCON:"); 1485 cil_log(CIL_INFO, " %s %s", genfscon->fs_str, genfscon->path_str); 1486 1487 if (genfscon->context != NULL) { 1488 cil_tree_print_context(genfscon->context); 1489 } else if (genfscon->context_str != NULL) { 1490 cil_log(CIL_INFO, " %s", genfscon->context_str); 1491 } 1492 1493 cil_log(CIL_INFO, "\n"); 1494 return; 1495 } 1496 case CIL_NETIFCON: { 1497 struct cil_netifcon *netifcon = node->data; 1498 cil_log(CIL_INFO, "NETIFCON %s", netifcon->interface_str); 1499 1500 if (netifcon->if_context != NULL) { 1501 cil_tree_print_context(netifcon->if_context); 1502 } else if (netifcon->if_context_str != NULL) { 1503 cil_log(CIL_INFO, " %s", netifcon->if_context_str); 1504 } 1505 1506 if (netifcon->packet_context != NULL) { 1507 cil_tree_print_context(netifcon->packet_context); 1508 } else if (netifcon->packet_context_str != NULL) { 1509 cil_log(CIL_INFO, " %s", netifcon->packet_context_str); 1510 } 1511 1512 cil_log(CIL_INFO, "\n"); 1513 return; 1514 } 1515 case CIL_IBENDPORTCON: { 1516 struct cil_ibendportcon *ibendportcon = node->data; 1517 1518 cil_log(CIL_INFO, "IBENDPORTCON: %s %u ", ibendportcon->dev_name_str, ibendportcon->port); 1519 1520 if (ibendportcon->context) 1521 cil_tree_print_context(ibendportcon->context); 1522 else if (ibendportcon->context_str) 1523 cil_log(CIL_INFO, " %s", ibendportcon->context_str); 1524 1525 cil_log(CIL_INFO, "\n"); 1526 return; 1527 } 1528 case CIL_PIRQCON: { 1529 struct cil_pirqcon *pirqcon = node->data; 1530 1531 cil_log(CIL_INFO, "PIRQCON %d", pirqcon->pirq); 1532 if (pirqcon->context != NULL) { 1533 cil_tree_print_context(pirqcon->context); 1534 } else { 1535 cil_log(CIL_INFO, " %s", pirqcon->context_str); 1536 } 1537 1538 cil_log(CIL_INFO, "\n"); 1539 return; 1540 } 1541 case CIL_IOMEMCON: { 1542 struct cil_iomemcon *iomemcon = node->data; 1543 1544 cil_log(CIL_INFO, "IOMEMCON ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high); 1545 if (iomemcon->context != NULL) { 1546 cil_tree_print_context(iomemcon->context); 1547 } else { 1548 cil_log(CIL_INFO, " %s", iomemcon->context_str); 1549 } 1550 1551 cil_log(CIL_INFO, "\n"); 1552 return; 1553 } 1554 case CIL_IOPORTCON: { 1555 struct cil_ioportcon *ioportcon = node->data; 1556 1557 cil_log(CIL_INFO, "IOPORTCON ( %d %d )", ioportcon->ioport_low, ioportcon->ioport_high); 1558 if (ioportcon->context != NULL) { 1559 cil_tree_print_context(ioportcon->context); 1560 } else { 1561 cil_log(CIL_INFO, " %s", ioportcon->context_str); 1562 } 1563 1564 cil_log(CIL_INFO, "\n"); 1565 return; 1566 } 1567 case CIL_PCIDEVICECON: { 1568 struct cil_pcidevicecon *pcidevicecon = node->data; 1569 1570 cil_log(CIL_INFO, "PCIDEVICECON %d", pcidevicecon->dev); 1571 if (pcidevicecon->context != NULL) { 1572 cil_tree_print_context(pcidevicecon->context); 1573 } else { 1574 cil_log(CIL_INFO, " %s", pcidevicecon->context_str); 1575 } 1576 1577 cil_log(CIL_INFO, "\n"); 1578 return; 1579 } 1580 case CIL_DEVICETREECON: { 1581 struct cil_devicetreecon *devicetreecon = node->data; 1582 1583 cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path); 1584 if (devicetreecon->context != NULL) { 1585 cil_tree_print_context(devicetreecon->context); 1586 } else { 1587 cil_log(CIL_INFO, " %s", devicetreecon->context_str); 1588 } 1589 1590 cil_log(CIL_INFO, "\n"); 1591 return; 1592 } 1593 case CIL_FSUSE: { 1594 struct cil_fsuse *fsuse = node->data; 1595 cil_log(CIL_INFO, "FSUSE: "); 1596 1597 if (fsuse->type == CIL_FSUSE_XATTR) { 1598 cil_log(CIL_INFO, "xattr "); 1599 } else if (fsuse->type == CIL_FSUSE_TASK) { 1600 cil_log(CIL_INFO, "task "); 1601 } else if (fsuse->type == CIL_FSUSE_TRANS) { 1602 cil_log(CIL_INFO, "trans "); 1603 } else { 1604 cil_log(CIL_INFO, "unknown "); 1605 } 1606 1607 cil_log(CIL_INFO, "%s ", fsuse->fs_str); 1608 1609 if (fsuse->context != NULL) { 1610 cil_tree_print_context(fsuse->context); 1611 } else { 1612 cil_log(CIL_INFO, " %s", fsuse->context_str); 1613 } 1614 1615 cil_log(CIL_INFO, "\n"); 1616 return; 1617 } 1618 case CIL_SID: { 1619 struct cil_sid *sid = node->data; 1620 cil_log(CIL_INFO, "SID: %s\n", sid->datum.name); 1621 return; 1622 } 1623 case CIL_SIDCONTEXT: { 1624 struct cil_sidcontext *sidcon = node->data; 1625 cil_log(CIL_INFO, "SIDCONTEXT: %s", sidcon->sid_str); 1626 1627 if (sidcon->context != NULL) { 1628 cil_tree_print_context(sidcon->context); 1629 } else { 1630 cil_log(CIL_INFO, " %s", sidcon->context_str); 1631 } 1632 1633 cil_log(CIL_INFO, "\n"); 1634 return; 1635 } 1636 case CIL_SIDORDER: { 1637 struct cil_sidorder *sidorder = node->data; 1638 struct cil_list_item *sid; 1639 1640 if (sidorder->sid_list_str == NULL) { 1641 cil_log(CIL_INFO, "SIDORDER: ()\n"); 1642 return; 1643 } 1644 1645 cil_log(CIL_INFO, "SIDORDER: ("); 1646 cil_list_for_each(sid, sidorder->sid_list_str) { 1647 cil_log(CIL_INFO, " %s", (char*)sid->data); 1648 } 1649 cil_log(CIL_INFO, " )\n"); 1650 return; 1651 } 1652 case CIL_POLICYCAP: { 1653 struct cil_policycap *polcap = node->data; 1654 cil_log(CIL_INFO, "POLICYCAP: %s\n", polcap->datum.name); 1655 return; 1656 } 1657 case CIL_MACRO: { 1658 struct cil_macro *macro = node->data; 1659 cil_log(CIL_INFO, "MACRO %s:", macro->datum.name); 1660 1661 if (macro->params != NULL && macro->params->head != NULL) { 1662 struct cil_list_item *curr_param; 1663 cil_log(CIL_INFO, " parameters: ("); 1664 cil_list_for_each(curr_param, macro->params) { 1665 cil_log(CIL_INFO, " flavor: %d, string: %s;", ((struct cil_param*)curr_param->data)->flavor, ((struct cil_param*)curr_param->data)->str); 1666 1667 } 1668 cil_log(CIL_INFO, " )"); 1669 } 1670 cil_log(CIL_INFO, "\n"); 1671 1672 return; 1673 } 1674 case CIL_CALL: { 1675 struct cil_call *call = node->data; 1676 cil_log(CIL_INFO, "CALL: macro name:"); 1677 1678 if (call->macro != NULL) { 1679 cil_log(CIL_INFO, " %s", call->macro->datum.name); 1680 } else { 1681 cil_log(CIL_INFO, " %s", call->macro_str); 1682 } 1683 1684 if (call->args != NULL) { 1685 cil_log(CIL_INFO, ", args: ( "); 1686 struct cil_list_item *item; 1687 cil_list_for_each(item, call->args) { 1688 struct cil_symtab_datum *datum = ((struct cil_args*)item->data)->arg; 1689 if (datum != NULL) { 1690 if (datum->nodes != NULL && datum->nodes->head != NULL) { 1691 cil_tree_print_node((struct cil_tree_node*)datum->nodes->head->data); 1692 } 1693 } else if (((struct cil_args*)item->data)->arg_str != NULL) { 1694 switch (item->flavor) { 1695 case CIL_TYPE: cil_log(CIL_INFO, "type:"); break; 1696 case CIL_USER: cil_log(CIL_INFO, "user:"); break; 1697 case CIL_ROLE: cil_log(CIL_INFO, "role:"); break; 1698 case CIL_SENS: cil_log(CIL_INFO, "sensitivity:"); break; 1699 case CIL_CAT: cil_log(CIL_INFO, "category:"); break; 1700 case CIL_CATSET: cil_log(CIL_INFO, "categoryset:"); break; 1701 case CIL_LEVEL: cil_log(CIL_INFO, "level:"); break; 1702 case CIL_CLASS: cil_log(CIL_INFO, "class:"); break; 1703 default: break; 1704 } 1705 cil_log(CIL_INFO, "%s ", ((struct cil_args*)item->data)->arg_str); 1706 } 1707 } 1708 cil_log(CIL_INFO, ")"); 1709 } 1710 1711 cil_log(CIL_INFO, "\n"); 1712 return; 1713 } 1714 case CIL_OPTIONAL: { 1715 struct cil_optional *optional = node->data; 1716 cil_log(CIL_INFO, "OPTIONAL: %s\n", optional->datum.name); 1717 return; 1718 } 1719 case CIL_IPADDR: { 1720 struct cil_ipaddr *ipaddr = node->data; 1721 char buf[256]; 1722 1723 inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256); 1724 cil_log(CIL_INFO, "IPADDR %s: %s\n", ipaddr->datum.name, buf); 1725 1726 break; 1727 } 1728 default : { 1729 cil_log(CIL_INFO, "CIL FLAVOR: %d\n", node->flavor); 1730 return; 1731 } 1732 } 1733 } 1734 } 1735 1736 void cil_tree_print(struct cil_tree_node *tree, uint32_t depth) 1737 { 1738 struct cil_tree_node *current = NULL; 1739 current = tree; 1740 uint32_t x = 0; 1741 1742 if (current != NULL) { 1743 if (current->cl_head == NULL) { 1744 if (current->flavor == CIL_NODE) { 1745 if (current->parent->cl_head == current) { 1746 cil_log(CIL_INFO, "%s", (char*)current->data); 1747 } else { 1748 cil_log(CIL_INFO, " %s", (char*)current->data); 1749 } 1750 } else if (current->flavor != CIL_PERM) { 1751 for (x = 0; x<depth; x++) { 1752 cil_log(CIL_INFO, "\t"); 1753 } 1754 cil_tree_print_node(current); 1755 } 1756 } else { 1757 if (current->parent != NULL) { 1758 cil_log(CIL_INFO, "\n"); 1759 for (x = 0; x<depth; x++) { 1760 cil_log(CIL_INFO, "\t"); 1761 } 1762 cil_log(CIL_INFO, "("); 1763 1764 if (current->flavor != CIL_NODE) { 1765 cil_tree_print_node(current); 1766 } 1767 } 1768 cil_tree_print(current->cl_head, depth + 1); 1769 } 1770 1771 if (current->next == NULL) { 1772 if ((current->parent != NULL) && (current->parent->cl_tail == current) && (current->parent->parent != NULL)) { 1773 if (current->flavor == CIL_PERM) { 1774 cil_log(CIL_INFO, ")\n"); 1775 } else if (current->flavor != CIL_NODE) { 1776 for (x = 0; x<depth-1; x++) { 1777 cil_log(CIL_INFO, "\t"); 1778 } 1779 cil_log(CIL_INFO, ")\n"); 1780 } else { 1781 cil_log(CIL_INFO, ")"); 1782 } 1783 } 1784 1785 if ((current->parent != NULL) && (current->parent->parent == NULL)) 1786 cil_log(CIL_INFO, "\n\n"); 1787 } else { 1788 cil_tree_print(current->next, depth); 1789 } 1790 } else { 1791 cil_log(CIL_INFO, "Tree is NULL\n"); 1792 } 1793 } 1794