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