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