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