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