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