xref: /aosp_15_r20/external/selinux/libsepol/cil/src/cil_policy.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker  * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3*2d543d20SAndroid Build Coastguard Worker  *
4*2d543d20SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
5*2d543d20SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
6*2d543d20SAndroid Build Coastguard Worker  *
7*2d543d20SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright notice,
8*2d543d20SAndroid Build Coastguard Worker  *       this list of conditions and the following disclaimer.
9*2d543d20SAndroid Build Coastguard Worker  *
10*2d543d20SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright notice,
11*2d543d20SAndroid Build Coastguard Worker  *       this list of conditions and the following disclaimer in the documentation
12*2d543d20SAndroid Build Coastguard Worker  *       and/or other materials provided with the distribution.
13*2d543d20SAndroid Build Coastguard Worker  *
14*2d543d20SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15*2d543d20SAndroid Build Coastguard Worker  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16*2d543d20SAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17*2d543d20SAndroid Build Coastguard Worker  * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18*2d543d20SAndroid Build Coastguard Worker  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19*2d543d20SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*2d543d20SAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21*2d543d20SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22*2d543d20SAndroid Build Coastguard Worker  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23*2d543d20SAndroid Build Coastguard Worker  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*2d543d20SAndroid Build Coastguard Worker  *
25*2d543d20SAndroid Build Coastguard Worker  * The views and conclusions contained in the software and documentation are those
26*2d543d20SAndroid Build Coastguard Worker  * of the authors and should not be interpreted as representing official policies,
27*2d543d20SAndroid Build Coastguard Worker  * either expressed or implied, of Tresys Technology, LLC.
28*2d543d20SAndroid Build Coastguard Worker  */
29*2d543d20SAndroid Build Coastguard Worker 
30*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
31*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
32*2d543d20SAndroid Build Coastguard Worker #include <string.h>
33*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
34*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
35*2d543d20SAndroid Build Coastguard Worker #include <inttypes.h>
36*2d543d20SAndroid Build Coastguard Worker 
37*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
38*2d543d20SAndroid Build Coastguard Worker #include <sepol/errcodes.h>
39*2d543d20SAndroid Build Coastguard Worker 
40*2d543d20SAndroid Build Coastguard Worker #include "cil_internal.h"
41*2d543d20SAndroid Build Coastguard Worker #include "cil_flavor.h"
42*2d543d20SAndroid Build Coastguard Worker #include "cil_find.h"
43*2d543d20SAndroid Build Coastguard Worker #include "cil_mem.h"
44*2d543d20SAndroid Build Coastguard Worker #include "cil_policy.h"
45*2d543d20SAndroid Build Coastguard Worker #include "cil_tree.h"
46*2d543d20SAndroid Build Coastguard Worker #include "cil_list.h"
47*2d543d20SAndroid Build Coastguard Worker #include "cil_symtab.h"
48*2d543d20SAndroid Build Coastguard Worker 
49*2d543d20SAndroid Build Coastguard Worker 
50*2d543d20SAndroid Build Coastguard Worker enum cil_statement_list {
51*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_COMMON = 1,
52*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_DEFAULT_USER,
53*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_DEFAULT_ROLE,
54*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_DEFAULT_TYPE,
55*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_DEFAULT_RANGE,
56*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_SENSALIAS,
57*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_CATALIAS,
58*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_MLSCONSTRAIN,
59*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_MLSVALIDATETRANS,
60*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_POLICYCAP,
61*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_TYPEATTRIBUTE,
62*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_ROLEATTRIBUTE,
63*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_BOOL,
64*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_TYPE,
65*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_TYPEALIAS,
66*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_ROLE,
67*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_ROLEALLOW,
68*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_ROLETRANSITION,
69*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_USER,
70*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_CONSTRAINT,
71*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_VALIDATETRANS,
72*2d543d20SAndroid Build Coastguard Worker 	CIL_LIST_NUM_LISTS
73*2d543d20SAndroid Build Coastguard Worker };
74*2d543d20SAndroid Build Coastguard Worker 
__cil_gather_statements_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)75*2d543d20SAndroid Build Coastguard Worker static int __cil_gather_statements_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
76*2d543d20SAndroid Build Coastguard Worker {
77*2d543d20SAndroid Build Coastguard Worker 	struct cil_list **lists;
78*2d543d20SAndroid Build Coastguard Worker 	int kind = 0;
79*2d543d20SAndroid Build Coastguard Worker 
80*2d543d20SAndroid Build Coastguard Worker 	lists = (struct cil_list **)extra_args;
81*2d543d20SAndroid Build Coastguard Worker 
82*2d543d20SAndroid Build Coastguard Worker 	switch (node->flavor) {
83*2d543d20SAndroid Build Coastguard Worker 	case CIL_BLOCK: {
84*2d543d20SAndroid Build Coastguard Worker 		struct cil_block *blk = node->data;
85*2d543d20SAndroid Build Coastguard Worker 		if (blk->is_abstract == CIL_TRUE) {
86*2d543d20SAndroid Build Coastguard Worker 			*finished = CIL_TREE_SKIP_HEAD;
87*2d543d20SAndroid Build Coastguard Worker 		}
88*2d543d20SAndroid Build Coastguard Worker 		break;
89*2d543d20SAndroid Build Coastguard Worker 	}
90*2d543d20SAndroid Build Coastguard Worker 	case CIL_MACRO:
91*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
92*2d543d20SAndroid Build Coastguard Worker 		break;
93*2d543d20SAndroid Build Coastguard Worker 	case CIL_BOOLEANIF:
94*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
95*2d543d20SAndroid Build Coastguard Worker 		break;
96*2d543d20SAndroid Build Coastguard Worker 	case CIL_COMMON:
97*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_COMMON;
98*2d543d20SAndroid Build Coastguard Worker 		break;
99*2d543d20SAndroid Build Coastguard Worker 	case CIL_DEFAULTUSER:
100*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_DEFAULT_USER;
101*2d543d20SAndroid Build Coastguard Worker 		break;
102*2d543d20SAndroid Build Coastguard Worker 	case CIL_DEFAULTROLE:
103*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_DEFAULT_ROLE;
104*2d543d20SAndroid Build Coastguard Worker 		break;
105*2d543d20SAndroid Build Coastguard Worker 	case CIL_DEFAULTTYPE:
106*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_DEFAULT_TYPE;
107*2d543d20SAndroid Build Coastguard Worker 		break;
108*2d543d20SAndroid Build Coastguard Worker 	case CIL_DEFAULTRANGE:
109*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_DEFAULT_RANGE;
110*2d543d20SAndroid Build Coastguard Worker 		break;
111*2d543d20SAndroid Build Coastguard Worker 	case CIL_SENSALIAS:
112*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_SENSALIAS;
113*2d543d20SAndroid Build Coastguard Worker 		break;
114*2d543d20SAndroid Build Coastguard Worker 	case CIL_CATALIAS:
115*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_CATALIAS;
116*2d543d20SAndroid Build Coastguard Worker 		break;
117*2d543d20SAndroid Build Coastguard Worker 	case CIL_MLSCONSTRAIN:
118*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_MLSCONSTRAIN;
119*2d543d20SAndroid Build Coastguard Worker 		break;
120*2d543d20SAndroid Build Coastguard Worker 	case CIL_MLSVALIDATETRANS:
121*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_MLSVALIDATETRANS;
122*2d543d20SAndroid Build Coastguard Worker 		break;
123*2d543d20SAndroid Build Coastguard Worker 	case CIL_POLICYCAP:
124*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_POLICYCAP;
125*2d543d20SAndroid Build Coastguard Worker 		break;
126*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPEATTRIBUTE: {
127*2d543d20SAndroid Build Coastguard Worker 		struct cil_typeattribute *attr = node->data;
128*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(attr->datum.fqn, "cil_gen_require") != 0) {
129*2d543d20SAndroid Build Coastguard Worker 			kind = CIL_LIST_TYPEATTRIBUTE;
130*2d543d20SAndroid Build Coastguard Worker 		}
131*2d543d20SAndroid Build Coastguard Worker 		break;
132*2d543d20SAndroid Build Coastguard Worker 	}
133*2d543d20SAndroid Build Coastguard Worker 	case CIL_ROLEATTRIBUTE: {
134*2d543d20SAndroid Build Coastguard Worker 		struct cil_roleattribute *attr = node->data;
135*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(attr->datum.fqn, "cil_gen_require") != 0) {
136*2d543d20SAndroid Build Coastguard Worker 			kind = CIL_LIST_ROLEATTRIBUTE;
137*2d543d20SAndroid Build Coastguard Worker 		}
138*2d543d20SAndroid Build Coastguard Worker 		break;
139*2d543d20SAndroid Build Coastguard Worker 	}
140*2d543d20SAndroid Build Coastguard Worker 	case CIL_BOOL:
141*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_BOOL;
142*2d543d20SAndroid Build Coastguard Worker 		break;
143*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPE:
144*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_TYPE;
145*2d543d20SAndroid Build Coastguard Worker 		break;
146*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPEALIAS:
147*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_TYPEALIAS;
148*2d543d20SAndroid Build Coastguard Worker 		break;
149*2d543d20SAndroid Build Coastguard Worker 	case CIL_ROLE: {
150*2d543d20SAndroid Build Coastguard Worker 		struct cil_role *role = node->data;
151*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(role->datum.fqn, "object_r") != 0) {
152*2d543d20SAndroid Build Coastguard Worker 			kind = CIL_LIST_ROLE;
153*2d543d20SAndroid Build Coastguard Worker 		}
154*2d543d20SAndroid Build Coastguard Worker 		break;
155*2d543d20SAndroid Build Coastguard Worker 	}
156*2d543d20SAndroid Build Coastguard Worker 	case CIL_ROLEALLOW:
157*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_ROLEALLOW;
158*2d543d20SAndroid Build Coastguard Worker 		break;
159*2d543d20SAndroid Build Coastguard Worker 	case CIL_ROLETRANSITION:
160*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_ROLETRANSITION;
161*2d543d20SAndroid Build Coastguard Worker 		break;
162*2d543d20SAndroid Build Coastguard Worker 	case CIL_USER:
163*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_USER;
164*2d543d20SAndroid Build Coastguard Worker 		break;
165*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONSTRAIN:
166*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_CONSTRAINT;
167*2d543d20SAndroid Build Coastguard Worker 		break;
168*2d543d20SAndroid Build Coastguard Worker 	case CIL_VALIDATETRANS:
169*2d543d20SAndroid Build Coastguard Worker 		kind = CIL_LIST_VALIDATETRANS;
170*2d543d20SAndroid Build Coastguard Worker 		break;
171*2d543d20SAndroid Build Coastguard Worker 	default:
172*2d543d20SAndroid Build Coastguard Worker 		break;
173*2d543d20SAndroid Build Coastguard Worker 	}
174*2d543d20SAndroid Build Coastguard Worker 
175*2d543d20SAndroid Build Coastguard Worker 	if (kind > 0) {
176*2d543d20SAndroid Build Coastguard Worker 		cil_list_append(lists[kind], node->flavor, node->data);
177*2d543d20SAndroid Build Coastguard Worker 	}
178*2d543d20SAndroid Build Coastguard Worker 
179*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_OK;
180*2d543d20SAndroid Build Coastguard Worker }
181*2d543d20SAndroid Build Coastguard Worker 
cil_gather_statements(struct cil_tree_node * start,struct cil_list * lists[])182*2d543d20SAndroid Build Coastguard Worker static void cil_gather_statements(struct cil_tree_node *start, struct cil_list *lists[])
183*2d543d20SAndroid Build Coastguard Worker {
184*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_gather_statements_helper, NULL, NULL, lists);
185*2d543d20SAndroid Build Coastguard Worker }
186*2d543d20SAndroid Build Coastguard Worker 
cil_simple_rules_to_policy(FILE * out,struct cil_list * rules,const char * kind)187*2d543d20SAndroid Build Coastguard Worker static void cil_simple_rules_to_policy(FILE *out, struct cil_list *rules, const char *kind)
188*2d543d20SAndroid Build Coastguard Worker {
189*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
190*2d543d20SAndroid Build Coastguard Worker 
191*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, rules) {
192*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s %s;\n", kind, DATUM(i1->data)->fqn);
193*2d543d20SAndroid Build Coastguard Worker 	}
194*2d543d20SAndroid Build Coastguard Worker }
195*2d543d20SAndroid Build Coastguard Worker 
cil_cats_to_policy(FILE * out,struct cil_cats * cats)196*2d543d20SAndroid Build Coastguard Worker static void cil_cats_to_policy(FILE *out, struct cil_cats *cats)
197*2d543d20SAndroid Build Coastguard Worker {
198*2d543d20SAndroid Build Coastguard Worker 	const char *lead = "";
199*2d543d20SAndroid Build Coastguard Worker 	struct cil_cat *first = NULL, *last = NULL, *cat;
200*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
201*2d543d20SAndroid Build Coastguard Worker 
202*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, cats->datum_expr) {
203*2d543d20SAndroid Build Coastguard Worker 		cat = i1->data;
204*2d543d20SAndroid Build Coastguard Worker 		if (first == NULL) {
205*2d543d20SAndroid Build Coastguard Worker 			first = cat;
206*2d543d20SAndroid Build Coastguard Worker 		} else if (last == NULL) {
207*2d543d20SAndroid Build Coastguard Worker 			if (cat->value == first->value + 1) {
208*2d543d20SAndroid Build Coastguard Worker 				last = cat;
209*2d543d20SAndroid Build Coastguard Worker 			} else {
210*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "%s%s", lead, DATUM(first)->fqn);
211*2d543d20SAndroid Build Coastguard Worker 				lead = ",";
212*2d543d20SAndroid Build Coastguard Worker 				first = cat;
213*2d543d20SAndroid Build Coastguard Worker 			}
214*2d543d20SAndroid Build Coastguard Worker 		} else if (cat->value == last->value + 1) {
215*2d543d20SAndroid Build Coastguard Worker 			last = cat;
216*2d543d20SAndroid Build Coastguard Worker 		} else {
217*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%s%s", lead, DATUM(first)->fqn);
218*2d543d20SAndroid Build Coastguard Worker 			lead = ",";
219*2d543d20SAndroid Build Coastguard Worker 			if (last->value >= first->value + 1) {
220*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, ".");
221*2d543d20SAndroid Build Coastguard Worker 			} else {
222*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, ",");
223*2d543d20SAndroid Build Coastguard Worker 			}
224*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%s", DATUM(last)->fqn);
225*2d543d20SAndroid Build Coastguard Worker 			first = cat;
226*2d543d20SAndroid Build Coastguard Worker 			last = NULL;
227*2d543d20SAndroid Build Coastguard Worker 		}
228*2d543d20SAndroid Build Coastguard Worker 	}
229*2d543d20SAndroid Build Coastguard Worker 	if (first) {
230*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s%s", lead, DATUM(first)->fqn);
231*2d543d20SAndroid Build Coastguard Worker 		if (last != NULL) {
232*2d543d20SAndroid Build Coastguard Worker 			if (last->value >= first->value + 1) {
233*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, ".");
234*2d543d20SAndroid Build Coastguard Worker 			} else {
235*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, ",");
236*2d543d20SAndroid Build Coastguard Worker 			}
237*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%s", DATUM(last)->fqn);
238*2d543d20SAndroid Build Coastguard Worker 		}
239*2d543d20SAndroid Build Coastguard Worker 	}
240*2d543d20SAndroid Build Coastguard Worker }
241*2d543d20SAndroid Build Coastguard Worker 
cil_level_to_policy(FILE * out,struct cil_level * level)242*2d543d20SAndroid Build Coastguard Worker static void cil_level_to_policy(FILE *out, struct cil_level *level)
243*2d543d20SAndroid Build Coastguard Worker {
244*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s", DATUM(level->sens)->fqn);
245*2d543d20SAndroid Build Coastguard Worker 	if (level->cats != NULL) {
246*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ":");
247*2d543d20SAndroid Build Coastguard Worker 		cil_cats_to_policy(out, level->cats);
248*2d543d20SAndroid Build Coastguard Worker 	}
249*2d543d20SAndroid Build Coastguard Worker }
250*2d543d20SAndroid Build Coastguard Worker 
cil_levels_simple_and_equal(struct cil_level * l1,struct cil_level * l2)251*2d543d20SAndroid Build Coastguard Worker static int cil_levels_simple_and_equal(struct cil_level *l1, struct cil_level *l2)
252*2d543d20SAndroid Build Coastguard Worker {
253*2d543d20SAndroid Build Coastguard Worker 	/* Mostly just want to detect s0 - s0 ranges */
254*2d543d20SAndroid Build Coastguard Worker 	if (l1 == l2)
255*2d543d20SAndroid Build Coastguard Worker 		return CIL_TRUE;
256*2d543d20SAndroid Build Coastguard Worker 
257*2d543d20SAndroid Build Coastguard Worker 	if (l1->sens == l2->sens && (l1->cats == NULL && l2->cats == NULL))
258*2d543d20SAndroid Build Coastguard Worker 		return CIL_TRUE;
259*2d543d20SAndroid Build Coastguard Worker 
260*2d543d20SAndroid Build Coastguard Worker 	return CIL_FALSE;
261*2d543d20SAndroid Build Coastguard Worker }
262*2d543d20SAndroid Build Coastguard Worker 
cil_levelrange_to_policy(FILE * out,struct cil_levelrange * lvlrange)263*2d543d20SAndroid Build Coastguard Worker static void cil_levelrange_to_policy(FILE *out, struct cil_levelrange *lvlrange)
264*2d543d20SAndroid Build Coastguard Worker {
265*2d543d20SAndroid Build Coastguard Worker 	cil_level_to_policy(out, lvlrange->low);
266*2d543d20SAndroid Build Coastguard Worker 	if (cil_levels_simple_and_equal(lvlrange->low, lvlrange->high) == CIL_FALSE) {
267*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, " - ");
268*2d543d20SAndroid Build Coastguard Worker 		cil_level_to_policy(out, lvlrange->high);
269*2d543d20SAndroid Build Coastguard Worker 	}
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker 
cil_context_to_policy(FILE * out,struct cil_context * context,int mls)272*2d543d20SAndroid Build Coastguard Worker static void cil_context_to_policy(FILE *out, struct cil_context *context, int mls)
273*2d543d20SAndroid Build Coastguard Worker {
274*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s:", DATUM(context->user)->fqn);
275*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s:", DATUM(context->role)->fqn);
276*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s", DATUM(context->type)->fqn);
277*2d543d20SAndroid Build Coastguard Worker 	if (mls) {
278*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ":");
279*2d543d20SAndroid Build Coastguard Worker 		cil_levelrange_to_policy(out, context->range);
280*2d543d20SAndroid Build Coastguard Worker 	}
281*2d543d20SAndroid Build Coastguard Worker }
282*2d543d20SAndroid Build Coastguard Worker 
cil_cond_expr_to_policy(FILE * out,struct cil_list * expr,int first)283*2d543d20SAndroid Build Coastguard Worker static void cil_cond_expr_to_policy(FILE *out, struct cil_list *expr, int first)
284*2d543d20SAndroid Build Coastguard Worker {
285*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1 = expr->head;
286*2d543d20SAndroid Build Coastguard Worker 
287*2d543d20SAndroid Build Coastguard Worker 	if (i1->flavor == CIL_OP) {
288*2d543d20SAndroid Build Coastguard Worker 		enum cil_flavor op = (enum cil_flavor)(uintptr_t)i1->data;
289*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "(");
290*2d543d20SAndroid Build Coastguard Worker 		switch (op) {
291*2d543d20SAndroid Build Coastguard Worker 		case CIL_NOT:
292*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "! ");
293*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
294*2d543d20SAndroid Build Coastguard Worker 			break;
295*2d543d20SAndroid Build Coastguard Worker 		case CIL_OR:
296*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
297*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " || ");
298*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE);
299*2d543d20SAndroid Build Coastguard Worker 			break;
300*2d543d20SAndroid Build Coastguard Worker 		case CIL_AND:
301*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
302*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " && ");
303*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE);
304*2d543d20SAndroid Build Coastguard Worker 			break;
305*2d543d20SAndroid Build Coastguard Worker 		case CIL_XOR:
306*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
307*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " ^ ");
308*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE);
309*2d543d20SAndroid Build Coastguard Worker 			break;
310*2d543d20SAndroid Build Coastguard Worker 		case CIL_EQ:
311*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
312*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " == ");
313*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE);
314*2d543d20SAndroid Build Coastguard Worker 			break;
315*2d543d20SAndroid Build Coastguard Worker 		case CIL_NEQ:
316*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE);
317*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " != ");
318*2d543d20SAndroid Build Coastguard Worker 			cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE);
319*2d543d20SAndroid Build Coastguard Worker 			break;
320*2d543d20SAndroid Build Coastguard Worker 		default:
321*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "???");
322*2d543d20SAndroid Build Coastguard Worker 			break;
323*2d543d20SAndroid Build Coastguard Worker 		}
324*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ")");
325*2d543d20SAndroid Build Coastguard Worker 	} else if (i1->flavor == CIL_DATUM) {
326*2d543d20SAndroid Build Coastguard Worker 		if (first == CIL_TRUE) {
327*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "(");
328*2d543d20SAndroid Build Coastguard Worker 		}
329*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s", DATUM(i1->data)->fqn);
330*2d543d20SAndroid Build Coastguard Worker 		if (first == CIL_TRUE) {
331*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, ")");
332*2d543d20SAndroid Build Coastguard Worker 		}
333*2d543d20SAndroid Build Coastguard Worker 	} else if (i1->flavor == CIL_LIST) {
334*2d543d20SAndroid Build Coastguard Worker 		cil_cond_expr_to_policy(out, i1->data, CIL_FALSE);
335*2d543d20SAndroid Build Coastguard Worker 	} else {
336*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "???");
337*2d543d20SAndroid Build Coastguard Worker 	}
338*2d543d20SAndroid Build Coastguard Worker }
339*2d543d20SAndroid Build Coastguard Worker 
__cil_userattribute_len(struct cil_db * db,struct cil_userattribute * attr)340*2d543d20SAndroid Build Coastguard Worker static size_t __cil_userattribute_len(struct cil_db *db, struct cil_userattribute *attr)
341*2d543d20SAndroid Build Coastguard Worker {
342*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *unode;
343*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
344*2d543d20SAndroid Build Coastguard Worker 	size_t len = 0;
345*2d543d20SAndroid Build Coastguard Worker 
346*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_positive_bit(attr->users, unode, i) {
347*2d543d20SAndroid Build Coastguard Worker 		len += strlen(DATUM(db->val_to_user[i])->fqn);
348*2d543d20SAndroid Build Coastguard Worker 		len++;
349*2d543d20SAndroid Build Coastguard Worker 	}
350*2d543d20SAndroid Build Coastguard Worker 
351*2d543d20SAndroid Build Coastguard Worker 	return len;
352*2d543d20SAndroid Build Coastguard Worker }
353*2d543d20SAndroid Build Coastguard Worker 
__cil_cons_leaf_operand_len(struct cil_db * db,struct cil_list_item * operand)354*2d543d20SAndroid Build Coastguard Worker static size_t __cil_cons_leaf_operand_len(struct cil_db *db, struct cil_list_item *operand)
355*2d543d20SAndroid Build Coastguard Worker {
356*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
357*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor flavor = operand->flavor;
358*2d543d20SAndroid Build Coastguard Worker 	size_t len = 0;
359*2d543d20SAndroid Build Coastguard Worker 
360*2d543d20SAndroid Build Coastguard Worker 	if (flavor == CIL_CONS_OPERAND) {
361*2d543d20SAndroid Build Coastguard Worker 		len = 2;
362*2d543d20SAndroid Build Coastguard Worker 	} else if (flavor == CIL_DATUM) {
363*2d543d20SAndroid Build Coastguard Worker 		struct cil_tree_node *node = NODE(operand->data);
364*2d543d20SAndroid Build Coastguard Worker 		if (node->flavor == CIL_USERATTRIBUTE) {
365*2d543d20SAndroid Build Coastguard Worker 			len = __cil_userattribute_len(db, operand->data);
366*2d543d20SAndroid Build Coastguard Worker 			len++; /* "{" */
367*2d543d20SAndroid Build Coastguard Worker 		} else {
368*2d543d20SAndroid Build Coastguard Worker 			len = strlen(DATUM(operand->data)->fqn);
369*2d543d20SAndroid Build Coastguard Worker 		}
370*2d543d20SAndroid Build Coastguard Worker 	} else if (flavor == CIL_LIST) {
371*2d543d20SAndroid Build Coastguard Worker 		len = 1; /* "{" */
372*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i1, (struct cil_list *)operand->data) {
373*2d543d20SAndroid Build Coastguard Worker 			struct cil_tree_node *node = NODE(operand->data);
374*2d543d20SAndroid Build Coastguard Worker 			if (node->flavor == CIL_USERATTRIBUTE) {
375*2d543d20SAndroid Build Coastguard Worker 				len = __cil_userattribute_len(db, operand->data);
376*2d543d20SAndroid Build Coastguard Worker 			} else {
377*2d543d20SAndroid Build Coastguard Worker 				len += strlen(DATUM(operand->data)->fqn);
378*2d543d20SAndroid Build Coastguard Worker 				len++; /* " " or "}" */
379*2d543d20SAndroid Build Coastguard Worker 			}
380*2d543d20SAndroid Build Coastguard Worker 		}
381*2d543d20SAndroid Build Coastguard Worker 	}
382*2d543d20SAndroid Build Coastguard Worker 
383*2d543d20SAndroid Build Coastguard Worker 	return len;
384*2d543d20SAndroid Build Coastguard Worker }
385*2d543d20SAndroid Build Coastguard Worker 
__cil_cons_leaf_op_len(struct cil_list_item * op)386*2d543d20SAndroid Build Coastguard Worker static size_t __cil_cons_leaf_op_len(struct cil_list_item *op)
387*2d543d20SAndroid Build Coastguard Worker {
388*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data;
389*2d543d20SAndroid Build Coastguard Worker 	size_t len;
390*2d543d20SAndroid Build Coastguard Worker 
391*2d543d20SAndroid Build Coastguard Worker 	switch (flavor) {
392*2d543d20SAndroid Build Coastguard Worker 	case CIL_EQ:
393*2d543d20SAndroid Build Coastguard Worker 		len = 4; /* " == " */
394*2d543d20SAndroid Build Coastguard Worker 		break;
395*2d543d20SAndroid Build Coastguard Worker 	case CIL_NEQ:
396*2d543d20SAndroid Build Coastguard Worker 		len = 4; /* " != " */
397*2d543d20SAndroid Build Coastguard Worker 		break;
398*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_DOM:
399*2d543d20SAndroid Build Coastguard Worker 		len = 5; /* " dom " */
400*2d543d20SAndroid Build Coastguard Worker 		break;
401*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_DOMBY:
402*2d543d20SAndroid Build Coastguard Worker 		len = 7; /* " domby " */
403*2d543d20SAndroid Build Coastguard Worker 		break;
404*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_INCOMP:
405*2d543d20SAndroid Build Coastguard Worker 		len = 8; /* " incomp " */
406*2d543d20SAndroid Build Coastguard Worker 		break;
407*2d543d20SAndroid Build Coastguard Worker 	default:
408*2d543d20SAndroid Build Coastguard Worker 		/* Should be impossible to be here */
409*2d543d20SAndroid Build Coastguard Worker 		len = 5; /* " ??? " */
410*2d543d20SAndroid Build Coastguard Worker 	}
411*2d543d20SAndroid Build Coastguard Worker 
412*2d543d20SAndroid Build Coastguard Worker 	return len;
413*2d543d20SAndroid Build Coastguard Worker }
414*2d543d20SAndroid Build Coastguard Worker 
cil_cons_expr_len(struct cil_db * db,struct cil_list * cons_expr)415*2d543d20SAndroid Build Coastguard Worker static size_t cil_cons_expr_len(struct cil_db *db, struct cil_list *cons_expr)
416*2d543d20SAndroid Build Coastguard Worker {
417*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
418*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor op;
419*2d543d20SAndroid Build Coastguard Worker 	size_t len;
420*2d543d20SAndroid Build Coastguard Worker 
421*2d543d20SAndroid Build Coastguard Worker 	i1 = cons_expr->head;
422*2d543d20SAndroid Build Coastguard Worker 
423*2d543d20SAndroid Build Coastguard Worker 	op = (enum cil_flavor)(uintptr_t)i1->data;
424*2d543d20SAndroid Build Coastguard Worker 	switch (op) {
425*2d543d20SAndroid Build Coastguard Worker 	case CIL_NOT:
426*2d543d20SAndroid Build Coastguard Worker 		len = 6; /* "(not )" */
427*2d543d20SAndroid Build Coastguard Worker 		len += cil_cons_expr_len(db, i1->next->data);
428*2d543d20SAndroid Build Coastguard Worker 		break;
429*2d543d20SAndroid Build Coastguard Worker 	case CIL_AND:
430*2d543d20SAndroid Build Coastguard Worker 		len = 7; /* "( and )" */
431*2d543d20SAndroid Build Coastguard Worker 		len += cil_cons_expr_len(db, i1->next->data);
432*2d543d20SAndroid Build Coastguard Worker 		len += cil_cons_expr_len(db, i1->next->next->data);
433*2d543d20SAndroid Build Coastguard Worker 		break;
434*2d543d20SAndroid Build Coastguard Worker 	case CIL_OR:
435*2d543d20SAndroid Build Coastguard Worker 		len = 6; /* "( or )" */
436*2d543d20SAndroid Build Coastguard Worker 		len += cil_cons_expr_len(db, i1->next->data);
437*2d543d20SAndroid Build Coastguard Worker 		len += cil_cons_expr_len(db, i1->next->next->data);
438*2d543d20SAndroid Build Coastguard Worker 		break;
439*2d543d20SAndroid Build Coastguard Worker 	default:
440*2d543d20SAndroid Build Coastguard Worker 		len = 2; /* "()" */
441*2d543d20SAndroid Build Coastguard Worker 		len += __cil_cons_leaf_operand_len(db, i1->next);
442*2d543d20SAndroid Build Coastguard Worker 		len += __cil_cons_leaf_op_len(i1);
443*2d543d20SAndroid Build Coastguard Worker 		len += __cil_cons_leaf_operand_len(db, i1->next->next);
444*2d543d20SAndroid Build Coastguard Worker 	}
445*2d543d20SAndroid Build Coastguard Worker 
446*2d543d20SAndroid Build Coastguard Worker 	return len;
447*2d543d20SAndroid Build Coastguard Worker }
448*2d543d20SAndroid Build Coastguard Worker 
__cil_userattribute_to_string(struct cil_db * db,struct cil_userattribute * attr,char * new)449*2d543d20SAndroid Build Coastguard Worker static char *__cil_userattribute_to_string(struct cil_db *db, struct cil_userattribute *attr, char *new)
450*2d543d20SAndroid Build Coastguard Worker {
451*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *unode;
452*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
453*2d543d20SAndroid Build Coastguard Worker 	char *str;
454*2d543d20SAndroid Build Coastguard Worker 	size_t len;
455*2d543d20SAndroid Build Coastguard Worker 
456*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_positive_bit(attr->users, unode, i) {
457*2d543d20SAndroid Build Coastguard Worker 		str = DATUM(db->val_to_user[i])->fqn;
458*2d543d20SAndroid Build Coastguard Worker 		len = strlen(str);
459*2d543d20SAndroid Build Coastguard Worker 		memcpy(new, str, len);
460*2d543d20SAndroid Build Coastguard Worker 		new += len;
461*2d543d20SAndroid Build Coastguard Worker 		*new++ = ' ';
462*2d543d20SAndroid Build Coastguard Worker 	}
463*2d543d20SAndroid Build Coastguard Worker 
464*2d543d20SAndroid Build Coastguard Worker 	return new;
465*2d543d20SAndroid Build Coastguard Worker }
466*2d543d20SAndroid Build Coastguard Worker 
__cil_cons_leaf_operand_to_string(struct cil_db * db,struct cil_list_item * operand,char * new)467*2d543d20SAndroid Build Coastguard Worker static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_list_item *operand, char *new)
468*2d543d20SAndroid Build Coastguard Worker {
469*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
470*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor flavor = operand->flavor;
471*2d543d20SAndroid Build Coastguard Worker 	const char *o_str;
472*2d543d20SAndroid Build Coastguard Worker 	size_t o_len;
473*2d543d20SAndroid Build Coastguard Worker 
474*2d543d20SAndroid Build Coastguard Worker 	if (flavor == CIL_CONS_OPERAND) {
475*2d543d20SAndroid Build Coastguard Worker 		enum cil_flavor o_flavor = (enum cil_flavor)(uintptr_t)operand->data;
476*2d543d20SAndroid Build Coastguard Worker 		switch (o_flavor) {
477*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_U1:
478*2d543d20SAndroid Build Coastguard Worker 			o_str = "u1";
479*2d543d20SAndroid Build Coastguard Worker 			break;
480*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_U2:
481*2d543d20SAndroid Build Coastguard Worker 			o_str = "u2";
482*2d543d20SAndroid Build Coastguard Worker 			break;
483*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_U3:
484*2d543d20SAndroid Build Coastguard Worker 			o_str = "u3";
485*2d543d20SAndroid Build Coastguard Worker 			break;
486*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_R1:
487*2d543d20SAndroid Build Coastguard Worker 			o_str = "r1";
488*2d543d20SAndroid Build Coastguard Worker 			break;
489*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_R2:
490*2d543d20SAndroid Build Coastguard Worker 			o_str = "r2";
491*2d543d20SAndroid Build Coastguard Worker 			break;
492*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_R3:
493*2d543d20SAndroid Build Coastguard Worker 			o_str = "r3";
494*2d543d20SAndroid Build Coastguard Worker 			break;
495*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_T1:
496*2d543d20SAndroid Build Coastguard Worker 			o_str = "t1";
497*2d543d20SAndroid Build Coastguard Worker 			break;
498*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_T2:
499*2d543d20SAndroid Build Coastguard Worker 			o_str = "t2";
500*2d543d20SAndroid Build Coastguard Worker 			break;
501*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_T3:
502*2d543d20SAndroid Build Coastguard Worker 			o_str = "t3";
503*2d543d20SAndroid Build Coastguard Worker 			break;
504*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_L1:
505*2d543d20SAndroid Build Coastguard Worker 			o_str = "l1";
506*2d543d20SAndroid Build Coastguard Worker 			break;
507*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_L2:
508*2d543d20SAndroid Build Coastguard Worker 			o_str = "l2";
509*2d543d20SAndroid Build Coastguard Worker 			break;
510*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_H1:
511*2d543d20SAndroid Build Coastguard Worker 			o_str = "h1";
512*2d543d20SAndroid Build Coastguard Worker 			break;
513*2d543d20SAndroid Build Coastguard Worker 		case CIL_CONS_H2:
514*2d543d20SAndroid Build Coastguard Worker 			o_str = "h2";
515*2d543d20SAndroid Build Coastguard Worker 			break;
516*2d543d20SAndroid Build Coastguard Worker 		default:
517*2d543d20SAndroid Build Coastguard Worker 			/* Impossible */
518*2d543d20SAndroid Build Coastguard Worker 			o_str = "??";
519*2d543d20SAndroid Build Coastguard Worker 		}
520*2d543d20SAndroid Build Coastguard Worker 		strcpy(new, o_str);
521*2d543d20SAndroid Build Coastguard Worker 		new += 2;
522*2d543d20SAndroid Build Coastguard Worker 	} else if (flavor == CIL_DATUM) {
523*2d543d20SAndroid Build Coastguard Worker 		struct cil_tree_node *node = NODE(operand->data);
524*2d543d20SAndroid Build Coastguard Worker 		if (node->flavor == CIL_USERATTRIBUTE) {
525*2d543d20SAndroid Build Coastguard Worker 			*new++ = '{';
526*2d543d20SAndroid Build Coastguard Worker 			new = __cil_userattribute_to_string(db, operand->data, new);
527*2d543d20SAndroid Build Coastguard Worker 			new--;
528*2d543d20SAndroid Build Coastguard Worker 			*new++ = '}';
529*2d543d20SAndroid Build Coastguard Worker 		} else {
530*2d543d20SAndroid Build Coastguard Worker 			o_str = DATUM(operand->data)->fqn;
531*2d543d20SAndroid Build Coastguard Worker 			o_len = strlen(o_str);
532*2d543d20SAndroid Build Coastguard Worker 			memcpy(new, o_str, o_len);
533*2d543d20SAndroid Build Coastguard Worker 			new += o_len;
534*2d543d20SAndroid Build Coastguard Worker 		}
535*2d543d20SAndroid Build Coastguard Worker 	} else if (flavor == CIL_LIST) {
536*2d543d20SAndroid Build Coastguard Worker 		*new++ = '{';
537*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i1, (struct cil_list *)operand->data) {
538*2d543d20SAndroid Build Coastguard Worker 			struct cil_tree_node *node = NODE(operand->data);
539*2d543d20SAndroid Build Coastguard Worker 			if (node->flavor == CIL_USERATTRIBUTE) {
540*2d543d20SAndroid Build Coastguard Worker 				new = __cil_userattribute_to_string(db, operand->data, new);
541*2d543d20SAndroid Build Coastguard Worker 			} else {
542*2d543d20SAndroid Build Coastguard Worker 				o_str = DATUM(operand->data)->fqn;
543*2d543d20SAndroid Build Coastguard Worker 				o_len = strlen(o_str);
544*2d543d20SAndroid Build Coastguard Worker 				memcpy(new, o_str, o_len);
545*2d543d20SAndroid Build Coastguard Worker 				new += o_len;
546*2d543d20SAndroid Build Coastguard Worker 				*new++ = ' ';
547*2d543d20SAndroid Build Coastguard Worker 			}
548*2d543d20SAndroid Build Coastguard Worker 		}
549*2d543d20SAndroid Build Coastguard Worker 		new--;
550*2d543d20SAndroid Build Coastguard Worker 		*new++ = '}';
551*2d543d20SAndroid Build Coastguard Worker 	}
552*2d543d20SAndroid Build Coastguard Worker 
553*2d543d20SAndroid Build Coastguard Worker 	return new;
554*2d543d20SAndroid Build Coastguard Worker }
555*2d543d20SAndroid Build Coastguard Worker 
__cil_cons_leaf_op_to_string(struct cil_list_item * op,char * new)556*2d543d20SAndroid Build Coastguard Worker static char *__cil_cons_leaf_op_to_string(struct cil_list_item *op, char *new)
557*2d543d20SAndroid Build Coastguard Worker {
558*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data;
559*2d543d20SAndroid Build Coastguard Worker 	const char *op_str;
560*2d543d20SAndroid Build Coastguard Worker 	size_t len;
561*2d543d20SAndroid Build Coastguard Worker 
562*2d543d20SAndroid Build Coastguard Worker 	switch (flavor) {
563*2d543d20SAndroid Build Coastguard Worker 	case CIL_EQ:
564*2d543d20SAndroid Build Coastguard Worker 		op_str = " == ";
565*2d543d20SAndroid Build Coastguard Worker 		len = 4;
566*2d543d20SAndroid Build Coastguard Worker 		break;
567*2d543d20SAndroid Build Coastguard Worker 	case CIL_NEQ:
568*2d543d20SAndroid Build Coastguard Worker 		op_str = " != ";
569*2d543d20SAndroid Build Coastguard Worker 		len = 4;
570*2d543d20SAndroid Build Coastguard Worker 		break;
571*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_DOM:
572*2d543d20SAndroid Build Coastguard Worker 		op_str = " dom ";
573*2d543d20SAndroid Build Coastguard Worker 		len = 5;
574*2d543d20SAndroid Build Coastguard Worker 		break;
575*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_DOMBY:
576*2d543d20SAndroid Build Coastguard Worker 		op_str = " domby ";
577*2d543d20SAndroid Build Coastguard Worker 		len = 7;
578*2d543d20SAndroid Build Coastguard Worker 		break;
579*2d543d20SAndroid Build Coastguard Worker 	case CIL_CONS_INCOMP:
580*2d543d20SAndroid Build Coastguard Worker 		op_str = " incomp ";
581*2d543d20SAndroid Build Coastguard Worker 		len = 8;
582*2d543d20SAndroid Build Coastguard Worker 		break;
583*2d543d20SAndroid Build Coastguard Worker 	default:
584*2d543d20SAndroid Build Coastguard Worker 		/* Should be impossible to be here */
585*2d543d20SAndroid Build Coastguard Worker 		op_str = " ??? ";
586*2d543d20SAndroid Build Coastguard Worker 		len = 5;
587*2d543d20SAndroid Build Coastguard Worker 	}
588*2d543d20SAndroid Build Coastguard Worker 
589*2d543d20SAndroid Build Coastguard Worker 	strcpy(new, op_str);
590*2d543d20SAndroid Build Coastguard Worker 	new += len;
591*2d543d20SAndroid Build Coastguard Worker 
592*2d543d20SAndroid Build Coastguard Worker 	return new;
593*2d543d20SAndroid Build Coastguard Worker }
594*2d543d20SAndroid Build Coastguard Worker 
__cil_cons_expr_to_string(struct cil_db * db,struct cil_list * cons_expr,char * new)595*2d543d20SAndroid Build Coastguard Worker static char *__cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_expr, char *new)
596*2d543d20SAndroid Build Coastguard Worker {
597*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
598*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor op;
599*2d543d20SAndroid Build Coastguard Worker 
600*2d543d20SAndroid Build Coastguard Worker 	i1 = cons_expr->head;
601*2d543d20SAndroid Build Coastguard Worker 
602*2d543d20SAndroid Build Coastguard Worker 	op = (enum cil_flavor)(uintptr_t)i1->data;
603*2d543d20SAndroid Build Coastguard Worker 	switch (op) {
604*2d543d20SAndroid Build Coastguard Worker 	case CIL_NOT:
605*2d543d20SAndroid Build Coastguard Worker 		*new++ = '(';
606*2d543d20SAndroid Build Coastguard Worker 		strcpy(new, "not ");
607*2d543d20SAndroid Build Coastguard Worker 		new += 4;
608*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_expr_to_string(db, i1->next->data, new);
609*2d543d20SAndroid Build Coastguard Worker 		*new++ = ')';
610*2d543d20SAndroid Build Coastguard Worker 		break;
611*2d543d20SAndroid Build Coastguard Worker 	case CIL_AND:
612*2d543d20SAndroid Build Coastguard Worker 		*new++ = '(';
613*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_expr_to_string(db, i1->next->data, new);
614*2d543d20SAndroid Build Coastguard Worker 		strcpy(new, " and ");
615*2d543d20SAndroid Build Coastguard Worker 		new += 5;
616*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_expr_to_string(db, i1->next->next->data, new);
617*2d543d20SAndroid Build Coastguard Worker 		*new++ = ')';
618*2d543d20SAndroid Build Coastguard Worker 		break;
619*2d543d20SAndroid Build Coastguard Worker 	case CIL_OR:
620*2d543d20SAndroid Build Coastguard Worker 		*new++ = '(';
621*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_expr_to_string(db, i1->next->data, new);
622*2d543d20SAndroid Build Coastguard Worker 		strcpy(new, " or ");
623*2d543d20SAndroid Build Coastguard Worker 		new += 4;
624*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_expr_to_string(db, i1->next->next->data, new);
625*2d543d20SAndroid Build Coastguard Worker 		*new++ = ')';
626*2d543d20SAndroid Build Coastguard Worker 		break;
627*2d543d20SAndroid Build Coastguard Worker 	default:
628*2d543d20SAndroid Build Coastguard Worker 		*new++ = '(';
629*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_leaf_operand_to_string(db, i1->next, new);
630*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_leaf_op_to_string(i1, new);
631*2d543d20SAndroid Build Coastguard Worker 		new = __cil_cons_leaf_operand_to_string(db, i1->next->next, new);
632*2d543d20SAndroid Build Coastguard Worker 		*new++ = ')';
633*2d543d20SAndroid Build Coastguard Worker 	}
634*2d543d20SAndroid Build Coastguard Worker 
635*2d543d20SAndroid Build Coastguard Worker 	return new;
636*2d543d20SAndroid Build Coastguard Worker }
637*2d543d20SAndroid Build Coastguard Worker 
cil_cons_expr_to_string(struct cil_db * db,struct cil_list * cons_expr)638*2d543d20SAndroid Build Coastguard Worker static char *cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_expr)
639*2d543d20SAndroid Build Coastguard Worker {
640*2d543d20SAndroid Build Coastguard Worker 	char *new, *tail;
641*2d543d20SAndroid Build Coastguard Worker 	size_t len = cil_cons_expr_len(db, cons_expr);
642*2d543d20SAndroid Build Coastguard Worker 
643*2d543d20SAndroid Build Coastguard Worker 	new = cil_malloc(len+1);
644*2d543d20SAndroid Build Coastguard Worker 	tail = __cil_cons_expr_to_string(db, cons_expr, new);
645*2d543d20SAndroid Build Coastguard Worker 	*tail = '\0';
646*2d543d20SAndroid Build Coastguard Worker 
647*2d543d20SAndroid Build Coastguard Worker 	return new;
648*2d543d20SAndroid Build Coastguard Worker }
649*2d543d20SAndroid Build Coastguard Worker 
cil_classperms_to_string(struct cil_classperms * classperms,struct cil_list * classperms_strs)650*2d543d20SAndroid Build Coastguard Worker static void cil_classperms_to_string(struct cil_classperms *classperms, struct cil_list *classperms_strs)
651*2d543d20SAndroid Build Coastguard Worker {
652*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
653*2d543d20SAndroid Build Coastguard Worker 	size_t len = 0;
654*2d543d20SAndroid Build Coastguard Worker 	char *new, *curr;
655*2d543d20SAndroid Build Coastguard Worker 
656*2d543d20SAndroid Build Coastguard Worker 	len += strlen(DATUM(classperms->class)->fqn) + 1;
657*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classperms->perms) {
658*2d543d20SAndroid Build Coastguard Worker 		len += strlen(DATUM(i1->data)->fqn) + 1;
659*2d543d20SAndroid Build Coastguard Worker 	}
660*2d543d20SAndroid Build Coastguard Worker 	len += 4; /* for "{ " and " }" */
661*2d543d20SAndroid Build Coastguard Worker 
662*2d543d20SAndroid Build Coastguard Worker 	new = cil_malloc(len);
663*2d543d20SAndroid Build Coastguard Worker 	curr = new;
664*2d543d20SAndroid Build Coastguard Worker 
665*2d543d20SAndroid Build Coastguard Worker 	curr[len-1] = '\0';
666*2d543d20SAndroid Build Coastguard Worker 
667*2d543d20SAndroid Build Coastguard Worker 	len = strlen(DATUM(classperms->class)->fqn);
668*2d543d20SAndroid Build Coastguard Worker 	memcpy(curr, DATUM(classperms->class)->fqn, len);
669*2d543d20SAndroid Build Coastguard Worker 	curr += len;
670*2d543d20SAndroid Build Coastguard Worker 	*curr++ = ' ';
671*2d543d20SAndroid Build Coastguard Worker 
672*2d543d20SAndroid Build Coastguard Worker 	*curr++ = '{';
673*2d543d20SAndroid Build Coastguard Worker 	*curr++ = ' ';
674*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classperms->perms) {
675*2d543d20SAndroid Build Coastguard Worker 		len = strlen(DATUM(i1->data)->fqn);
676*2d543d20SAndroid Build Coastguard Worker 		memcpy(curr, DATUM(i1->data)->fqn, len);
677*2d543d20SAndroid Build Coastguard Worker 		curr += len;
678*2d543d20SAndroid Build Coastguard Worker 		*curr++ = ' ';
679*2d543d20SAndroid Build Coastguard Worker 	}
680*2d543d20SAndroid Build Coastguard Worker 	*curr++ = '}';
681*2d543d20SAndroid Build Coastguard Worker 
682*2d543d20SAndroid Build Coastguard Worker 	cil_list_append(classperms_strs, CIL_STRING, new);
683*2d543d20SAndroid Build Coastguard Worker }
684*2d543d20SAndroid Build Coastguard Worker 
cil_classperms_to_strings(struct cil_list * classperms,struct cil_list * classperms_strs)685*2d543d20SAndroid Build Coastguard Worker static void cil_classperms_to_strings(struct cil_list *classperms, struct cil_list *classperms_strs)
686*2d543d20SAndroid Build Coastguard Worker {
687*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
688*2d543d20SAndroid Build Coastguard Worker 
689*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classperms) {
690*2d543d20SAndroid Build Coastguard Worker 		if (i1->flavor == CIL_CLASSPERMS) {
691*2d543d20SAndroid Build Coastguard Worker 			struct cil_classperms *cp = i1->data;
692*2d543d20SAndroid Build Coastguard Worker 			if (FLAVOR(cp->class) == CIL_CLASS) {
693*2d543d20SAndroid Build Coastguard Worker 				cil_classperms_to_string(cp, classperms_strs);
694*2d543d20SAndroid Build Coastguard Worker 			} else { /* MAP */
695*2d543d20SAndroid Build Coastguard Worker 				struct cil_list_item *i2 = NULL;
696*2d543d20SAndroid Build Coastguard Worker 				cil_list_for_each(i2, cp->perms) {
697*2d543d20SAndroid Build Coastguard Worker 					struct cil_perm *cmp = i2->data;
698*2d543d20SAndroid Build Coastguard Worker 					cil_classperms_to_strings(cmp->classperms, classperms_strs);
699*2d543d20SAndroid Build Coastguard Worker 				}
700*2d543d20SAndroid Build Coastguard Worker 			}
701*2d543d20SAndroid Build Coastguard Worker 		} else { /* SET */
702*2d543d20SAndroid Build Coastguard Worker 			struct cil_classperms_set *cp_set = i1->data;
703*2d543d20SAndroid Build Coastguard Worker 			struct cil_classpermission *cp = cp_set->set;
704*2d543d20SAndroid Build Coastguard Worker 			cil_classperms_to_strings(cp->classperms, classperms_strs);
705*2d543d20SAndroid Build Coastguard Worker 		}
706*2d543d20SAndroid Build Coastguard Worker 	}
707*2d543d20SAndroid Build Coastguard Worker }
708*2d543d20SAndroid Build Coastguard Worker 
cil_class_decls_to_policy(FILE * out,struct cil_list * classorder)709*2d543d20SAndroid Build Coastguard Worker static void cil_class_decls_to_policy(FILE *out, struct cil_list *classorder)
710*2d543d20SAndroid Build Coastguard Worker {
711*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
712*2d543d20SAndroid Build Coastguard Worker 
713*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classorder) {
714*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "class %s\n", DATUM(i1->data)->fqn);
715*2d543d20SAndroid Build Coastguard Worker 	}
716*2d543d20SAndroid Build Coastguard Worker }
717*2d543d20SAndroid Build Coastguard Worker 
cil_sid_decls_to_policy(FILE * out,struct cil_list * sidorder)718*2d543d20SAndroid Build Coastguard Worker static void cil_sid_decls_to_policy(FILE *out, struct cil_list *sidorder)
719*2d543d20SAndroid Build Coastguard Worker {
720*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
721*2d543d20SAndroid Build Coastguard Worker 
722*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, sidorder) {
723*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "sid %s\n", DATUM(i1->data)->fqn);
724*2d543d20SAndroid Build Coastguard Worker 	}
725*2d543d20SAndroid Build Coastguard Worker }
726*2d543d20SAndroid Build Coastguard Worker 
cil_commons_to_policy(FILE * out,struct cil_list * commons)727*2d543d20SAndroid Build Coastguard Worker static void cil_commons_to_policy(FILE *out, struct cil_list *commons)
728*2d543d20SAndroid Build Coastguard Worker {
729*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
730*2d543d20SAndroid Build Coastguard Worker 	struct cil_class* common;
731*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *node;
732*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *perm;
733*2d543d20SAndroid Build Coastguard Worker 
734*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, commons) {
735*2d543d20SAndroid Build Coastguard Worker 		common = i1->data;
736*2d543d20SAndroid Build Coastguard Worker 		node = NODE(&common->datum);
737*2d543d20SAndroid Build Coastguard Worker 		perm = node->cl_head;
738*2d543d20SAndroid Build Coastguard Worker 
739*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "common %s {", common->datum.fqn);
740*2d543d20SAndroid Build Coastguard Worker 		while (perm != NULL) {
741*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%s ", DATUM(perm->data)->fqn);
742*2d543d20SAndroid Build Coastguard Worker 			perm = perm->next;
743*2d543d20SAndroid Build Coastguard Worker 		}
744*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "}\n");
745*2d543d20SAndroid Build Coastguard Worker 	}
746*2d543d20SAndroid Build Coastguard Worker }
747*2d543d20SAndroid Build Coastguard Worker 
cil_classes_to_policy(FILE * out,struct cil_list * classorder)748*2d543d20SAndroid Build Coastguard Worker static void cil_classes_to_policy(FILE *out, struct cil_list *classorder)
749*2d543d20SAndroid Build Coastguard Worker {
750*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
751*2d543d20SAndroid Build Coastguard Worker 	struct cil_class *class;
752*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *node;
753*2d543d20SAndroid Build Coastguard Worker 
754*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classorder) {
755*2d543d20SAndroid Build Coastguard Worker 		class = i1->data;
756*2d543d20SAndroid Build Coastguard Worker 		node = NODE(&class->datum);
757*2d543d20SAndroid Build Coastguard Worker 
758*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "class %s", class->datum.fqn);
759*2d543d20SAndroid Build Coastguard Worker 		if (class->common != NULL) {
760*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " inherits %s", class->common->datum.fqn);
761*2d543d20SAndroid Build Coastguard Worker 		}
762*2d543d20SAndroid Build Coastguard Worker 		if (node->cl_head != NULL) {
763*2d543d20SAndroid Build Coastguard Worker 			struct cil_tree_node *perm = node->cl_head;
764*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " {");
765*2d543d20SAndroid Build Coastguard Worker 			while (perm != NULL) {
766*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", DATUM(perm->data)->fqn);
767*2d543d20SAndroid Build Coastguard Worker 				perm = perm->next;
768*2d543d20SAndroid Build Coastguard Worker 			}
769*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " }");
770*2d543d20SAndroid Build Coastguard Worker 		}
771*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
772*2d543d20SAndroid Build Coastguard Worker 	}
773*2d543d20SAndroid Build Coastguard Worker }
774*2d543d20SAndroid Build Coastguard Worker 
cil_defaults_to_policy(FILE * out,struct cil_list * defaults,const char * kind)775*2d543d20SAndroid Build Coastguard Worker static void cil_defaults_to_policy(FILE *out, struct cil_list *defaults, const char *kind)
776*2d543d20SAndroid Build Coastguard Worker {
777*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2, *i3;
778*2d543d20SAndroid Build Coastguard Worker 	struct cil_default *def;
779*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
780*2d543d20SAndroid Build Coastguard Worker 
781*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, defaults) {
782*2d543d20SAndroid Build Coastguard Worker 		def = i1->data;
783*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s {",kind);
784*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, def->class_datums) {
785*2d543d20SAndroid Build Coastguard Worker 			class_list = cil_expand_class(i2->data);
786*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i3, class_list) {
787*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", DATUM(i3->data)->fqn);
788*2d543d20SAndroid Build Coastguard Worker 			}
789*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&class_list, CIL_FALSE);
790*2d543d20SAndroid Build Coastguard Worker 		}
791*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, " }");
792*2d543d20SAndroid Build Coastguard Worker 		if (def->object == CIL_DEFAULT_SOURCE) {
793*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s",CIL_KEY_SOURCE);
794*2d543d20SAndroid Build Coastguard Worker 		} else if (def->object == CIL_DEFAULT_TARGET) {
795*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s",CIL_KEY_TARGET);
796*2d543d20SAndroid Build Coastguard Worker 		}
797*2d543d20SAndroid Build Coastguard Worker 		fprintf(out,";\n");
798*2d543d20SAndroid Build Coastguard Worker 	}
799*2d543d20SAndroid Build Coastguard Worker }
800*2d543d20SAndroid Build Coastguard Worker 
cil_default_ranges_to_policy(FILE * out,struct cil_list * defaults)801*2d543d20SAndroid Build Coastguard Worker static void cil_default_ranges_to_policy(FILE *out, struct cil_list *defaults)
802*2d543d20SAndroid Build Coastguard Worker {
803*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2, *i3;
804*2d543d20SAndroid Build Coastguard Worker 	struct cil_defaultrange *def;
805*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
806*2d543d20SAndroid Build Coastguard Worker 
807*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, defaults) {
808*2d543d20SAndroid Build Coastguard Worker 		def = i1->data;
809*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "default_range {");
810*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, def->class_datums) {
811*2d543d20SAndroid Build Coastguard Worker 			class_list = cil_expand_class(i2->data);
812*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i3, class_list) {
813*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", DATUM(i3->data)->fqn);
814*2d543d20SAndroid Build Coastguard Worker 			}
815*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&class_list, CIL_FALSE);
816*2d543d20SAndroid Build Coastguard Worker 		}
817*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, " }");
818*2d543d20SAndroid Build Coastguard Worker 
819*2d543d20SAndroid Build Coastguard Worker 		switch (def->object_range) {
820*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_SOURCE_LOW:
821*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_LOW);
822*2d543d20SAndroid Build Coastguard Worker 			break;
823*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_SOURCE_HIGH:
824*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_HIGH);
825*2d543d20SAndroid Build Coastguard Worker 			break;
826*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_SOURCE_LOW_HIGH:
827*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_LOW_HIGH);
828*2d543d20SAndroid Build Coastguard Worker 			break;
829*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_TARGET_LOW:
830*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_LOW);
831*2d543d20SAndroid Build Coastguard Worker 			break;
832*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_TARGET_HIGH:
833*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_HIGH);
834*2d543d20SAndroid Build Coastguard Worker 			break;
835*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_TARGET_LOW_HIGH:
836*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_LOW_HIGH);
837*2d543d20SAndroid Build Coastguard Worker 			break;
838*2d543d20SAndroid Build Coastguard Worker 		case CIL_DEFAULT_GLBLUB:
839*2d543d20SAndroid Build Coastguard Worker 			fprintf(out," %s", CIL_KEY_GLBLUB);
840*2d543d20SAndroid Build Coastguard Worker 			break;
841*2d543d20SAndroid Build Coastguard Worker 		default:
842*2d543d20SAndroid Build Coastguard Worker 			break;
843*2d543d20SAndroid Build Coastguard Worker 		}
844*2d543d20SAndroid Build Coastguard Worker 		fprintf(out,";\n");
845*2d543d20SAndroid Build Coastguard Worker 	}
846*2d543d20SAndroid Build Coastguard Worker }
847*2d543d20SAndroid Build Coastguard Worker 
cil_sensitivities_to_policy(FILE * out,struct cil_list * sensorder,struct cil_list * all_aliases)848*2d543d20SAndroid Build Coastguard Worker static void cil_sensitivities_to_policy(FILE *out, struct cil_list *sensorder, struct cil_list *all_aliases)
849*2d543d20SAndroid Build Coastguard Worker {
850*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
851*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *sens;
852*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *aliases = NULL;
853*2d543d20SAndroid Build Coastguard Worker 	struct cil_alias *alias;
854*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *actual;
855*2d543d20SAndroid Build Coastguard Worker 	int num_aliases;
856*2d543d20SAndroid Build Coastguard Worker 
857*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, sensorder) {
858*2d543d20SAndroid Build Coastguard Worker 		sens = i1->data;
859*2d543d20SAndroid Build Coastguard Worker 		num_aliases = 0;
860*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, all_aliases) {
861*2d543d20SAndroid Build Coastguard Worker 			alias = i2->data;
862*2d543d20SAndroid Build Coastguard Worker 			actual = alias->actual;
863*2d543d20SAndroid Build Coastguard Worker 			if (sens == actual) {
864*2d543d20SAndroid Build Coastguard Worker 				if (num_aliases == 0) {
865*2d543d20SAndroid Build Coastguard Worker 					cil_list_init(&aliases, CIL_LIST);
866*2d543d20SAndroid Build Coastguard Worker 				}
867*2d543d20SAndroid Build Coastguard Worker 				cil_list_append(aliases, CIL_SENSALIAS, alias);
868*2d543d20SAndroid Build Coastguard Worker 				num_aliases++;
869*2d543d20SAndroid Build Coastguard Worker 			}
870*2d543d20SAndroid Build Coastguard Worker 		}
871*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "sensitivity %s", sens->datum.fqn);
872*2d543d20SAndroid Build Coastguard Worker 		if (num_aliases > 0) {
873*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " alias");
874*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
875*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " {");
876*2d543d20SAndroid Build Coastguard Worker 			}
877*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, aliases) {
878*2d543d20SAndroid Build Coastguard Worker 				alias = i2->data;
879*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", alias->datum.fqn);
880*2d543d20SAndroid Build Coastguard Worker 			}
881*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
882*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " }");
883*2d543d20SAndroid Build Coastguard Worker 			}
884*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&aliases, CIL_FALSE);
885*2d543d20SAndroid Build Coastguard Worker 		}
886*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
887*2d543d20SAndroid Build Coastguard Worker 	}
888*2d543d20SAndroid Build Coastguard Worker }
889*2d543d20SAndroid Build Coastguard Worker 
cil_dominance_to_policy(FILE * out,struct cil_list * sensorder)890*2d543d20SAndroid Build Coastguard Worker static void cil_dominance_to_policy(FILE *out, struct cil_list *sensorder)
891*2d543d20SAndroid Build Coastguard Worker {
892*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *item;
893*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *sens;
894*2d543d20SAndroid Build Coastguard Worker 
895*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "dominance {");
896*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(item, sensorder) {
897*2d543d20SAndroid Build Coastguard Worker 		sens = item->data;
898*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, " %s", sens->datum.fqn);
899*2d543d20SAndroid Build Coastguard Worker 	}
900*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, " }\n");
901*2d543d20SAndroid Build Coastguard Worker }
902*2d543d20SAndroid Build Coastguard Worker 
cil_categories_to_policy(FILE * out,struct cil_list * catorder,struct cil_list * all_aliases)903*2d543d20SAndroid Build Coastguard Worker static void cil_categories_to_policy(FILE *out, struct cil_list *catorder, struct cil_list *all_aliases)
904*2d543d20SAndroid Build Coastguard Worker {
905*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
906*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *cat;
907*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *aliases = NULL;
908*2d543d20SAndroid Build Coastguard Worker 	struct cil_alias *alias;
909*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *actual;
910*2d543d20SAndroid Build Coastguard Worker 	int num_aliases;
911*2d543d20SAndroid Build Coastguard Worker 
912*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, catorder) {
913*2d543d20SAndroid Build Coastguard Worker 		cat = i1->data;
914*2d543d20SAndroid Build Coastguard Worker 		num_aliases = 0;
915*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, all_aliases) {
916*2d543d20SAndroid Build Coastguard Worker 			alias = i2->data;
917*2d543d20SAndroid Build Coastguard Worker 			actual = alias->actual;
918*2d543d20SAndroid Build Coastguard Worker 			if (cat == actual) {
919*2d543d20SAndroid Build Coastguard Worker 				if (num_aliases == 0) {
920*2d543d20SAndroid Build Coastguard Worker 					cil_list_init(&aliases, CIL_LIST);
921*2d543d20SAndroid Build Coastguard Worker 				}
922*2d543d20SAndroid Build Coastguard Worker 				cil_list_append(aliases, CIL_CATALIAS, alias);
923*2d543d20SAndroid Build Coastguard Worker 				num_aliases++;
924*2d543d20SAndroid Build Coastguard Worker 			}
925*2d543d20SAndroid Build Coastguard Worker 		}
926*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "category %s",cat->datum.fqn);
927*2d543d20SAndroid Build Coastguard Worker 		if (num_aliases > 0) {
928*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " alias");
929*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
930*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " { ");
931*2d543d20SAndroid Build Coastguard Worker 			}
932*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, aliases) {
933*2d543d20SAndroid Build Coastguard Worker 				alias = i2->data;
934*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", alias->datum.fqn);
935*2d543d20SAndroid Build Coastguard Worker 			}
936*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
937*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " }");
938*2d543d20SAndroid Build Coastguard Worker 			}
939*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&aliases, CIL_FALSE);
940*2d543d20SAndroid Build Coastguard Worker 		}
941*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
942*2d543d20SAndroid Build Coastguard Worker 	}
943*2d543d20SAndroid Build Coastguard Worker }
944*2d543d20SAndroid Build Coastguard Worker 
cil_levels_to_policy(FILE * out,struct cil_list * sensorder)945*2d543d20SAndroid Build Coastguard Worker static void cil_levels_to_policy(FILE *out, struct cil_list *sensorder)
946*2d543d20SAndroid Build Coastguard Worker {
947*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
948*2d543d20SAndroid Build Coastguard Worker 	struct cil_sens *sens;
949*2d543d20SAndroid Build Coastguard Worker 
950*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, sensorder) {
951*2d543d20SAndroid Build Coastguard Worker 		sens = i1->data;
952*2d543d20SAndroid Build Coastguard Worker 		if (sens->cats_list) {
953*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, sens->cats_list) {
954*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "level %s:",sens->datum.fqn);
955*2d543d20SAndroid Build Coastguard Worker 				cil_cats_to_policy(out, i2->data);
956*2d543d20SAndroid Build Coastguard Worker 				fprintf(out,";\n");
957*2d543d20SAndroid Build Coastguard Worker 			}
958*2d543d20SAndroid Build Coastguard Worker 		} else {
959*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "level %s;\n",sens->datum.fqn);
960*2d543d20SAndroid Build Coastguard Worker 		}
961*2d543d20SAndroid Build Coastguard Worker 	}
962*2d543d20SAndroid Build Coastguard Worker }
963*2d543d20SAndroid Build Coastguard Worker 
cil_mlsconstrains_to_policy(FILE * out,struct cil_db * db,struct cil_list * mlsconstrains)964*2d543d20SAndroid Build Coastguard Worker static void cil_mlsconstrains_to_policy(FILE *out, struct cil_db *db, struct cil_list *mlsconstrains)
965*2d543d20SAndroid Build Coastguard Worker {
966*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
967*2d543d20SAndroid Build Coastguard Worker 	struct cil_constrain *cons;
968*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *classperms_strs;
969*2d543d20SAndroid Build Coastguard Worker 	char *cp_str;
970*2d543d20SAndroid Build Coastguard Worker 	char *expr_str;
971*2d543d20SAndroid Build Coastguard Worker 
972*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, mlsconstrains) {
973*2d543d20SAndroid Build Coastguard Worker 		cons = i1->data;
974*2d543d20SAndroid Build Coastguard Worker 		cil_list_init(&classperms_strs, CIL_LIST);
975*2d543d20SAndroid Build Coastguard Worker 		cil_classperms_to_strings(cons->classperms, classperms_strs);
976*2d543d20SAndroid Build Coastguard Worker 		expr_str = cil_cons_expr_to_string(db, cons->datum_expr);
977*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, classperms_strs) {
978*2d543d20SAndroid Build Coastguard Worker 			cp_str = i2->data;
979*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "mlsconstrain %s %s;\n", cp_str, expr_str);
980*2d543d20SAndroid Build Coastguard Worker 			free(cp_str);
981*2d543d20SAndroid Build Coastguard Worker 		}
982*2d543d20SAndroid Build Coastguard Worker 		free(expr_str);
983*2d543d20SAndroid Build Coastguard Worker 		cil_list_destroy(&classperms_strs, CIL_FALSE);
984*2d543d20SAndroid Build Coastguard Worker 	}
985*2d543d20SAndroid Build Coastguard Worker }
986*2d543d20SAndroid Build Coastguard Worker 
cil_validatetrans_to_policy(FILE * out,struct cil_db * db,struct cil_list * validatetrans,char * kind)987*2d543d20SAndroid Build Coastguard Worker static void cil_validatetrans_to_policy(FILE *out, struct cil_db *db, struct cil_list *validatetrans, char *kind)
988*2d543d20SAndroid Build Coastguard Worker {
989*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
990*2d543d20SAndroid Build Coastguard Worker 	struct cil_validatetrans *trans;
991*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
992*2d543d20SAndroid Build Coastguard Worker 	struct cil_class *class;
993*2d543d20SAndroid Build Coastguard Worker 	char *expr_str;
994*2d543d20SAndroid Build Coastguard Worker 
995*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, validatetrans) {
996*2d543d20SAndroid Build Coastguard Worker 		trans = i1->data;
997*2d543d20SAndroid Build Coastguard Worker 		class_list = cil_expand_class(trans->class);
998*2d543d20SAndroid Build Coastguard Worker 		expr_str = cil_cons_expr_to_string(db, trans->datum_expr);
999*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, class_list) {
1000*2d543d20SAndroid Build Coastguard Worker 			class = i2->data;
1001*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%s %s %s;\n", kind, class->datum.fqn, expr_str);
1002*2d543d20SAndroid Build Coastguard Worker 		}
1003*2d543d20SAndroid Build Coastguard Worker 		free(expr_str);
1004*2d543d20SAndroid Build Coastguard Worker 		cil_list_destroy(&class_list, CIL_FALSE);
1005*2d543d20SAndroid Build Coastguard Worker 	}
1006*2d543d20SAndroid Build Coastguard Worker }
1007*2d543d20SAndroid Build Coastguard Worker 
cil_bools_to_policy(FILE * out,struct cil_list * bools)1008*2d543d20SAndroid Build Coastguard Worker static void cil_bools_to_policy(FILE *out, struct cil_list *bools)
1009*2d543d20SAndroid Build Coastguard Worker {
1010*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1011*2d543d20SAndroid Build Coastguard Worker 	struct cil_bool *boolean;
1012*2d543d20SAndroid Build Coastguard Worker 	const char *value;
1013*2d543d20SAndroid Build Coastguard Worker 
1014*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, bools) {
1015*2d543d20SAndroid Build Coastguard Worker 		boolean = i1->data;
1016*2d543d20SAndroid Build Coastguard Worker 		value = boolean->value ? "true" : "false";
1017*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "bool %s %s;\n", boolean->datum.fqn, value);
1018*2d543d20SAndroid Build Coastguard Worker 	}
1019*2d543d20SAndroid Build Coastguard Worker }
1020*2d543d20SAndroid Build Coastguard Worker 
cil_typealiases_to_policy(FILE * out,struct cil_list * types,struct cil_list * all_aliases)1021*2d543d20SAndroid Build Coastguard Worker static void cil_typealiases_to_policy(FILE *out, struct cil_list *types, struct cil_list *all_aliases)
1022*2d543d20SAndroid Build Coastguard Worker {
1023*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1024*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *type;
1025*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *aliases = NULL;
1026*2d543d20SAndroid Build Coastguard Worker 	struct cil_alias *alias;
1027*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *actual;
1028*2d543d20SAndroid Build Coastguard Worker 	int num_aliases;
1029*2d543d20SAndroid Build Coastguard Worker 
1030*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, types) {
1031*2d543d20SAndroid Build Coastguard Worker 		type = i1->data;
1032*2d543d20SAndroid Build Coastguard Worker 		num_aliases = 0;
1033*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, all_aliases) {
1034*2d543d20SAndroid Build Coastguard Worker 			alias = i2->data;
1035*2d543d20SAndroid Build Coastguard Worker 			actual = alias->actual;
1036*2d543d20SAndroid Build Coastguard Worker 			if (type == actual) {
1037*2d543d20SAndroid Build Coastguard Worker 				if (num_aliases == 0) {
1038*2d543d20SAndroid Build Coastguard Worker 					cil_list_init(&aliases, CIL_LIST);
1039*2d543d20SAndroid Build Coastguard Worker 				}
1040*2d543d20SAndroid Build Coastguard Worker 				cil_list_append(aliases, CIL_TYPEALIAS, alias);
1041*2d543d20SAndroid Build Coastguard Worker 				num_aliases++;
1042*2d543d20SAndroid Build Coastguard Worker 			}
1043*2d543d20SAndroid Build Coastguard Worker 		}
1044*2d543d20SAndroid Build Coastguard Worker 		if (num_aliases > 0) {
1045*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "typealias %s alias", type->datum.fqn);
1046*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
1047*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " {");
1048*2d543d20SAndroid Build Coastguard Worker 			}
1049*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, aliases) {
1050*2d543d20SAndroid Build Coastguard Worker 				alias = i2->data;
1051*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", alias->datum.fqn);
1052*2d543d20SAndroid Build Coastguard Worker 			}
1053*2d543d20SAndroid Build Coastguard Worker 			if (num_aliases > 1) {
1054*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " }");
1055*2d543d20SAndroid Build Coastguard Worker 			}
1056*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, ";\n");
1057*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&aliases, CIL_FALSE);
1058*2d543d20SAndroid Build Coastguard Worker 		}
1059*2d543d20SAndroid Build Coastguard Worker 	}
1060*2d543d20SAndroid Build Coastguard Worker }
1061*2d543d20SAndroid Build Coastguard Worker 
cil_typebounds_to_policy(FILE * out,struct cil_list * types)1062*2d543d20SAndroid Build Coastguard Worker static void cil_typebounds_to_policy(FILE *out, struct cil_list *types)
1063*2d543d20SAndroid Build Coastguard Worker {
1064*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1065*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *child;
1066*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *parent;
1067*2d543d20SAndroid Build Coastguard Worker 
1068*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, types) {
1069*2d543d20SAndroid Build Coastguard Worker 		child = i1->data;
1070*2d543d20SAndroid Build Coastguard Worker 		if (child->bounds != NULL) {
1071*2d543d20SAndroid Build Coastguard Worker 			parent = child->bounds;
1072*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "typebounds %s %s;\n", parent->datum.fqn, child->datum.fqn);
1073*2d543d20SAndroid Build Coastguard Worker 		}
1074*2d543d20SAndroid Build Coastguard Worker 	}
1075*2d543d20SAndroid Build Coastguard Worker }
1076*2d543d20SAndroid Build Coastguard Worker 
cil_typeattributes_to_policy(FILE * out,struct cil_list * types,struct cil_list * attributes)1077*2d543d20SAndroid Build Coastguard Worker static void cil_typeattributes_to_policy(FILE *out, struct cil_list *types, struct cil_list *attributes)
1078*2d543d20SAndroid Build Coastguard Worker {
1079*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1080*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *type;
1081*2d543d20SAndroid Build Coastguard Worker 	struct cil_typeattribute *attribute;
1082*2d543d20SAndroid Build Coastguard Worker 	int first = CIL_TRUE;
1083*2d543d20SAndroid Build Coastguard Worker 
1084*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, types) {
1085*2d543d20SAndroid Build Coastguard Worker 		type = i1->data;
1086*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, attributes) {
1087*2d543d20SAndroid Build Coastguard Worker 			attribute = i2->data;
1088*2d543d20SAndroid Build Coastguard Worker 			if (!attribute->keep)
1089*2d543d20SAndroid Build Coastguard Worker 				continue;
1090*2d543d20SAndroid Build Coastguard Worker 			if (ebitmap_get_bit(attribute->types, type->value)) {
1091*2d543d20SAndroid Build Coastguard Worker 				if (first) {
1092*2d543d20SAndroid Build Coastguard Worker 					fprintf(out, "typeattribute %s %s", type->datum.fqn, attribute->datum.fqn);
1093*2d543d20SAndroid Build Coastguard Worker 					first = CIL_FALSE;
1094*2d543d20SAndroid Build Coastguard Worker 				} else {
1095*2d543d20SAndroid Build Coastguard Worker 					fprintf(out, ", %s", attribute->datum.fqn);
1096*2d543d20SAndroid Build Coastguard Worker 				}
1097*2d543d20SAndroid Build Coastguard Worker 			}
1098*2d543d20SAndroid Build Coastguard Worker 		}
1099*2d543d20SAndroid Build Coastguard Worker 		if (!first) {
1100*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, ";\n");
1101*2d543d20SAndroid Build Coastguard Worker 			first = CIL_TRUE;
1102*2d543d20SAndroid Build Coastguard Worker 		}
1103*2d543d20SAndroid Build Coastguard Worker 	}
1104*2d543d20SAndroid Build Coastguard Worker }
1105*2d543d20SAndroid Build Coastguard Worker 
cil_xperms_to_policy(FILE * out,struct cil_permissionx * permx)1106*2d543d20SAndroid Build Coastguard Worker static void cil_xperms_to_policy(FILE *out, struct cil_permissionx *permx)
1107*2d543d20SAndroid Build Coastguard Worker {
1108*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *node;
1109*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, first = 0, last = 0;
1110*2d543d20SAndroid Build Coastguard Worker 	int need_first = CIL_TRUE, need_last = CIL_TRUE;
1111*2d543d20SAndroid Build Coastguard Worker 	const char *kind;
1112*2d543d20SAndroid Build Coastguard Worker 
1113*2d543d20SAndroid Build Coastguard Worker 	if (permx->kind == CIL_PERMX_KIND_IOCTL) {
1114*2d543d20SAndroid Build Coastguard Worker 		kind = "ioctl";
1115*2d543d20SAndroid Build Coastguard Worker 	} else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
1116*2d543d20SAndroid Build Coastguard Worker 		kind = "nlmsg";
1117*2d543d20SAndroid Build Coastguard Worker 	} else {
1118*2d543d20SAndroid Build Coastguard Worker 		kind = "???";
1119*2d543d20SAndroid Build Coastguard Worker 	}
1120*2d543d20SAndroid Build Coastguard Worker 
1121*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s %s {", DATUM(permx->obj)->fqn, kind);
1122*2d543d20SAndroid Build Coastguard Worker 
1123*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_positive_bit(permx->perms, node, i) {
1124*2d543d20SAndroid Build Coastguard Worker 		if (need_first == CIL_TRUE) {
1125*2d543d20SAndroid Build Coastguard Worker 			first = i;
1126*2d543d20SAndroid Build Coastguard Worker 			need_first = CIL_FALSE;
1127*2d543d20SAndroid Build Coastguard Worker 		} else if (need_last == CIL_TRUE) {
1128*2d543d20SAndroid Build Coastguard Worker 			if (i == first+1) {
1129*2d543d20SAndroid Build Coastguard Worker 				last = i;
1130*2d543d20SAndroid Build Coastguard Worker 				need_last = CIL_FALSE;
1131*2d543d20SAndroid Build Coastguard Worker 			} else {
1132*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " 0x%x", first);
1133*2d543d20SAndroid Build Coastguard Worker 				first = i;
1134*2d543d20SAndroid Build Coastguard Worker 			}
1135*2d543d20SAndroid Build Coastguard Worker 		} else if (i == last+1) {
1136*2d543d20SAndroid Build Coastguard Worker 			last = i;
1137*2d543d20SAndroid Build Coastguard Worker 		} else {
1138*2d543d20SAndroid Build Coastguard Worker 			if (last > first+1) {
1139*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " 0x%x-0x%x", first, last);
1140*2d543d20SAndroid Build Coastguard Worker 			} else {
1141*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " 0x%x 0x%x", first, last);
1142*2d543d20SAndroid Build Coastguard Worker 			}
1143*2d543d20SAndroid Build Coastguard Worker 			first = i;
1144*2d543d20SAndroid Build Coastguard Worker 			need_last = CIL_TRUE;
1145*2d543d20SAndroid Build Coastguard Worker 		}
1146*2d543d20SAndroid Build Coastguard Worker 	}
1147*2d543d20SAndroid Build Coastguard Worker 	if (need_first == CIL_FALSE) {
1148*2d543d20SAndroid Build Coastguard Worker 		if (need_last == CIL_FALSE) {
1149*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " 0x%x-0x%x", first, last);
1150*2d543d20SAndroid Build Coastguard Worker 		} else {
1151*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " 0x%x", first);
1152*2d543d20SAndroid Build Coastguard Worker 		}
1153*2d543d20SAndroid Build Coastguard Worker 	}
1154*2d543d20SAndroid Build Coastguard Worker 	fprintf(out," }");
1155*2d543d20SAndroid Build Coastguard Worker }
1156*2d543d20SAndroid Build Coastguard Worker 
cil_av_rulex_to_policy(FILE * out,struct cil_avrule * rule)1157*2d543d20SAndroid Build Coastguard Worker static void cil_av_rulex_to_policy(FILE *out, struct cil_avrule *rule)
1158*2d543d20SAndroid Build Coastguard Worker {
1159*2d543d20SAndroid Build Coastguard Worker 	const char *kind;
1160*2d543d20SAndroid Build Coastguard Worker 	struct cil_symtab_datum *src, *tgt;
1161*2d543d20SAndroid Build Coastguard Worker 
1162*2d543d20SAndroid Build Coastguard Worker 	src = rule->src;
1163*2d543d20SAndroid Build Coastguard Worker 	tgt = rule->tgt;
1164*2d543d20SAndroid Build Coastguard Worker 
1165*2d543d20SAndroid Build Coastguard Worker 	switch (rule->rule_kind) {
1166*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_ALLOWED:
1167*2d543d20SAndroid Build Coastguard Worker 		kind = "allowxperm";
1168*2d543d20SAndroid Build Coastguard Worker 		break;
1169*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_AUDITALLOW:
1170*2d543d20SAndroid Build Coastguard Worker 		kind = "auditallowxperm";
1171*2d543d20SAndroid Build Coastguard Worker 		break;
1172*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_DONTAUDIT:
1173*2d543d20SAndroid Build Coastguard Worker 		kind = "dontauditxperm";
1174*2d543d20SAndroid Build Coastguard Worker 		break;
1175*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_NEVERALLOW:
1176*2d543d20SAndroid Build Coastguard Worker 		kind = "neverallowxperm";
1177*2d543d20SAndroid Build Coastguard Worker 		break;
1178*2d543d20SAndroid Build Coastguard Worker 	default:
1179*2d543d20SAndroid Build Coastguard Worker 		kind = "???";
1180*2d543d20SAndroid Build Coastguard Worker 		break;
1181*2d543d20SAndroid Build Coastguard Worker 	}
1182*2d543d20SAndroid Build Coastguard Worker 
1183*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "%s %s %s : ", kind, src->fqn, tgt->fqn);
1184*2d543d20SAndroid Build Coastguard Worker 	cil_xperms_to_policy(out, rule->perms.x.permx);
1185*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, ";\n");
1186*2d543d20SAndroid Build Coastguard Worker }
1187*2d543d20SAndroid Build Coastguard Worker 
cil_av_rule_to_policy(FILE * out,struct cil_avrule * rule)1188*2d543d20SAndroid Build Coastguard Worker static void cil_av_rule_to_policy(FILE *out, struct cil_avrule *rule)
1189*2d543d20SAndroid Build Coastguard Worker {
1190*2d543d20SAndroid Build Coastguard Worker 	const char *kind;
1191*2d543d20SAndroid Build Coastguard Worker 	struct cil_symtab_datum *src, *tgt;
1192*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *classperms_strs;
1193*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1194*2d543d20SAndroid Build Coastguard Worker 
1195*2d543d20SAndroid Build Coastguard Worker 	src = rule->src;
1196*2d543d20SAndroid Build Coastguard Worker 	tgt = rule->tgt;
1197*2d543d20SAndroid Build Coastguard Worker 
1198*2d543d20SAndroid Build Coastguard Worker 	switch (rule->rule_kind) {
1199*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_ALLOWED:
1200*2d543d20SAndroid Build Coastguard Worker 		kind = "allow";
1201*2d543d20SAndroid Build Coastguard Worker 		break;
1202*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_AUDITALLOW:
1203*2d543d20SAndroid Build Coastguard Worker 		kind = "auditallow";
1204*2d543d20SAndroid Build Coastguard Worker 		break;
1205*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_DONTAUDIT:
1206*2d543d20SAndroid Build Coastguard Worker 		kind = "dontaudit";
1207*2d543d20SAndroid Build Coastguard Worker 		break;
1208*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE_NEVERALLOW:
1209*2d543d20SAndroid Build Coastguard Worker 		kind = "neverallow";
1210*2d543d20SAndroid Build Coastguard Worker 		break;
1211*2d543d20SAndroid Build Coastguard Worker 	default:
1212*2d543d20SAndroid Build Coastguard Worker 		kind = "???";
1213*2d543d20SAndroid Build Coastguard Worker 		break;
1214*2d543d20SAndroid Build Coastguard Worker 	}
1215*2d543d20SAndroid Build Coastguard Worker 
1216*2d543d20SAndroid Build Coastguard Worker 	cil_list_init(&classperms_strs, CIL_LIST);
1217*2d543d20SAndroid Build Coastguard Worker 	cil_classperms_to_strings(rule->perms.classperms, classperms_strs);
1218*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, classperms_strs) {
1219*2d543d20SAndroid Build Coastguard Worker 		char *cp_str = i1->data;
1220*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s %s %s : %s;\n", kind, src->fqn, tgt->fqn, cp_str);
1221*2d543d20SAndroid Build Coastguard Worker 		free(cp_str);
1222*2d543d20SAndroid Build Coastguard Worker 	}
1223*2d543d20SAndroid Build Coastguard Worker 	cil_list_destroy(&classperms_strs, CIL_FALSE);
1224*2d543d20SAndroid Build Coastguard Worker }
1225*2d543d20SAndroid Build Coastguard Worker 
cil_type_rule_to_policy(FILE * out,struct cil_type_rule * rule)1226*2d543d20SAndroid Build Coastguard Worker static void cil_type_rule_to_policy(FILE *out, struct cil_type_rule *rule)
1227*2d543d20SAndroid Build Coastguard Worker {
1228*2d543d20SAndroid Build Coastguard Worker 	const char *kind;
1229*2d543d20SAndroid Build Coastguard Worker 	struct cil_symtab_datum *src, *tgt, *res;
1230*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
1231*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1232*2d543d20SAndroid Build Coastguard Worker 
1233*2d543d20SAndroid Build Coastguard Worker 	src = rule->src;
1234*2d543d20SAndroid Build Coastguard Worker 	tgt = rule->tgt;
1235*2d543d20SAndroid Build Coastguard Worker 	res = rule->result;
1236*2d543d20SAndroid Build Coastguard Worker 
1237*2d543d20SAndroid Build Coastguard Worker 	switch (rule->rule_kind) {
1238*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPE_TRANSITION:
1239*2d543d20SAndroid Build Coastguard Worker 		kind = "type_transition";
1240*2d543d20SAndroid Build Coastguard Worker 		break;
1241*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPE_MEMBER:
1242*2d543d20SAndroid Build Coastguard Worker 		kind = "type_member";
1243*2d543d20SAndroid Build Coastguard Worker 		break;
1244*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPE_CHANGE:
1245*2d543d20SAndroid Build Coastguard Worker 		kind = "type_change";
1246*2d543d20SAndroid Build Coastguard Worker 		break;
1247*2d543d20SAndroid Build Coastguard Worker 	default:
1248*2d543d20SAndroid Build Coastguard Worker 		kind = "???";
1249*2d543d20SAndroid Build Coastguard Worker 		break;
1250*2d543d20SAndroid Build Coastguard Worker 	}
1251*2d543d20SAndroid Build Coastguard Worker 
1252*2d543d20SAndroid Build Coastguard Worker 	class_list = cil_expand_class(rule->obj);
1253*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, class_list) {
1254*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%s %s %s : %s %s;\n", kind, src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn);
1255*2d543d20SAndroid Build Coastguard Worker 	}
1256*2d543d20SAndroid Build Coastguard Worker 	cil_list_destroy(&class_list, CIL_FALSE);
1257*2d543d20SAndroid Build Coastguard Worker }
1258*2d543d20SAndroid Build Coastguard Worker 
cil_nametypetransition_to_policy(FILE * out,struct cil_nametypetransition * trans)1259*2d543d20SAndroid Build Coastguard Worker static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetransition *trans)
1260*2d543d20SAndroid Build Coastguard Worker {
1261*2d543d20SAndroid Build Coastguard Worker 	struct cil_symtab_datum *src, *tgt, *name, *res;
1262*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
1263*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1264*2d543d20SAndroid Build Coastguard Worker 
1265*2d543d20SAndroid Build Coastguard Worker 	src = trans->src;
1266*2d543d20SAndroid Build Coastguard Worker 	tgt = trans->tgt;
1267*2d543d20SAndroid Build Coastguard Worker 	name = trans->name;
1268*2d543d20SAndroid Build Coastguard Worker 	res = trans->result;
1269*2d543d20SAndroid Build Coastguard Worker 
1270*2d543d20SAndroid Build Coastguard Worker 	class_list = cil_expand_class(trans->obj);
1271*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, class_list) {
1272*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "type_transition %s %s : %s %s \"%s\";\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->fqn);
1273*2d543d20SAndroid Build Coastguard Worker 	}
1274*2d543d20SAndroid Build Coastguard Worker 	cil_list_destroy(&class_list, CIL_FALSE);
1275*2d543d20SAndroid Build Coastguard Worker }
1276*2d543d20SAndroid Build Coastguard Worker 
cil_rangetransition_to_policy(FILE * out,struct cil_rangetransition * trans)1277*2d543d20SAndroid Build Coastguard Worker static void cil_rangetransition_to_policy(FILE *out, struct cil_rangetransition *trans)
1278*2d543d20SAndroid Build Coastguard Worker {
1279*2d543d20SAndroid Build Coastguard Worker 	struct cil_symtab_datum *src, *exec;
1280*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
1281*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1282*2d543d20SAndroid Build Coastguard Worker 
1283*2d543d20SAndroid Build Coastguard Worker 	src = trans->src;
1284*2d543d20SAndroid Build Coastguard Worker 	exec = trans->exec;
1285*2d543d20SAndroid Build Coastguard Worker 
1286*2d543d20SAndroid Build Coastguard Worker 	class_list = cil_expand_class(trans->obj);
1287*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, class_list) {
1288*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "range_transition %s %s : %s ", src->fqn, exec->fqn, DATUM(i1->data)->fqn);
1289*2d543d20SAndroid Build Coastguard Worker 		cil_levelrange_to_policy(out, trans->range);
1290*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1291*2d543d20SAndroid Build Coastguard Worker 	}
1292*2d543d20SAndroid Build Coastguard Worker 	cil_list_destroy(&class_list, CIL_FALSE);
1293*2d543d20SAndroid Build Coastguard Worker }
1294*2d543d20SAndroid Build Coastguard Worker 
cil_typepermissive_to_policy(FILE * out,struct cil_typepermissive * rule)1295*2d543d20SAndroid Build Coastguard Worker static void cil_typepermissive_to_policy(FILE *out, struct cil_typepermissive *rule)
1296*2d543d20SAndroid Build Coastguard Worker {
1297*2d543d20SAndroid Build Coastguard Worker 	fprintf(out, "permissive %s;\n", DATUM(rule->type)->fqn);
1298*2d543d20SAndroid Build Coastguard Worker }
1299*2d543d20SAndroid Build Coastguard Worker 
1300*2d543d20SAndroid Build Coastguard Worker struct block_te_rules_extra {
1301*2d543d20SAndroid Build Coastguard Worker 	FILE *out;
1302*2d543d20SAndroid Build Coastguard Worker 	enum cil_flavor flavor;
1303*2d543d20SAndroid Build Coastguard Worker 	uint32_t rule_kind;
1304*2d543d20SAndroid Build Coastguard Worker };
1305*2d543d20SAndroid Build Coastguard Worker 
__cil_block_te_rules_to_policy_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1306*2d543d20SAndroid Build Coastguard Worker static int __cil_block_te_rules_to_policy_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
1307*2d543d20SAndroid Build Coastguard Worker {
1308*2d543d20SAndroid Build Coastguard Worker 	struct block_te_rules_extra *args = extra_args;
1309*2d543d20SAndroid Build Coastguard Worker 
1310*2d543d20SAndroid Build Coastguard Worker 	switch (node->flavor) {
1311*2d543d20SAndroid Build Coastguard Worker 	case CIL_BLOCK: {
1312*2d543d20SAndroid Build Coastguard Worker 		struct cil_block *blk = node->data;
1313*2d543d20SAndroid Build Coastguard Worker 		if (blk->is_abstract == CIL_TRUE) {
1314*2d543d20SAndroid Build Coastguard Worker 			*finished = CIL_TREE_SKIP_HEAD;
1315*2d543d20SAndroid Build Coastguard Worker 		}
1316*2d543d20SAndroid Build Coastguard Worker 		break;
1317*2d543d20SAndroid Build Coastguard Worker 	}
1318*2d543d20SAndroid Build Coastguard Worker 	case CIL_MACRO:
1319*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
1320*2d543d20SAndroid Build Coastguard Worker 		break;
1321*2d543d20SAndroid Build Coastguard Worker 	case CIL_BOOLEANIF:
1322*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
1323*2d543d20SAndroid Build Coastguard Worker 		break;
1324*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULE:
1325*2d543d20SAndroid Build Coastguard Worker 	case CIL_AVRULEX:
1326*2d543d20SAndroid Build Coastguard Worker 		if (args->flavor == node->flavor) {
1327*2d543d20SAndroid Build Coastguard Worker 			struct cil_avrule *rule = node->data;
1328*2d543d20SAndroid Build Coastguard Worker 			if (args->rule_kind == rule->rule_kind) {
1329*2d543d20SAndroid Build Coastguard Worker 				if (rule->is_extended) {
1330*2d543d20SAndroid Build Coastguard Worker 					cil_av_rulex_to_policy(args->out, rule);
1331*2d543d20SAndroid Build Coastguard Worker 				} else {
1332*2d543d20SAndroid Build Coastguard Worker 					cil_av_rule_to_policy(args->out, rule);
1333*2d543d20SAndroid Build Coastguard Worker 				}
1334*2d543d20SAndroid Build Coastguard Worker 			}
1335*2d543d20SAndroid Build Coastguard Worker 		}
1336*2d543d20SAndroid Build Coastguard Worker 		break;
1337*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPE_RULE:
1338*2d543d20SAndroid Build Coastguard Worker 		if (args->flavor == node->flavor) {
1339*2d543d20SAndroid Build Coastguard Worker 			struct cil_type_rule *rule = node->data;
1340*2d543d20SAndroid Build Coastguard Worker 			if (args->rule_kind == rule->rule_kind) {
1341*2d543d20SAndroid Build Coastguard Worker 				cil_type_rule_to_policy(args->out, rule);
1342*2d543d20SAndroid Build Coastguard Worker 			}
1343*2d543d20SAndroid Build Coastguard Worker 		}
1344*2d543d20SAndroid Build Coastguard Worker 
1345*2d543d20SAndroid Build Coastguard Worker 		break;
1346*2d543d20SAndroid Build Coastguard Worker 	case CIL_NAMETYPETRANSITION:
1347*2d543d20SAndroid Build Coastguard Worker 		if (args->flavor == node->flavor) {
1348*2d543d20SAndroid Build Coastguard Worker 			cil_nametypetransition_to_policy(args->out, node->data);
1349*2d543d20SAndroid Build Coastguard Worker 		}
1350*2d543d20SAndroid Build Coastguard Worker 		break;
1351*2d543d20SAndroid Build Coastguard Worker 	case CIL_RANGETRANSITION:
1352*2d543d20SAndroid Build Coastguard Worker 		if (args->flavor == node->flavor) {
1353*2d543d20SAndroid Build Coastguard Worker 			cil_rangetransition_to_policy(args->out, node->data);
1354*2d543d20SAndroid Build Coastguard Worker 		}
1355*2d543d20SAndroid Build Coastguard Worker 
1356*2d543d20SAndroid Build Coastguard Worker 		break;
1357*2d543d20SAndroid Build Coastguard Worker 	case CIL_TYPEPERMISSIVE:
1358*2d543d20SAndroid Build Coastguard Worker 		if (args->flavor == node->flavor) {
1359*2d543d20SAndroid Build Coastguard Worker 			cil_typepermissive_to_policy(args->out, node->data);
1360*2d543d20SAndroid Build Coastguard Worker 		}
1361*2d543d20SAndroid Build Coastguard Worker 		break;
1362*2d543d20SAndroid Build Coastguard Worker 	default:
1363*2d543d20SAndroid Build Coastguard Worker 		break;
1364*2d543d20SAndroid Build Coastguard Worker 	}
1365*2d543d20SAndroid Build Coastguard Worker 
1366*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_OK;
1367*2d543d20SAndroid Build Coastguard Worker }
1368*2d543d20SAndroid Build Coastguard Worker 
cil_block_te_rules_to_policy(FILE * out,struct cil_tree_node * start,int mls)1369*2d543d20SAndroid Build Coastguard Worker static void cil_block_te_rules_to_policy(FILE *out, struct cil_tree_node *start, int mls)
1370*2d543d20SAndroid Build Coastguard Worker {
1371*2d543d20SAndroid Build Coastguard Worker 	struct block_te_rules_extra args;
1372*2d543d20SAndroid Build Coastguard Worker 
1373*2d543d20SAndroid Build Coastguard Worker 	args.out = out;
1374*2d543d20SAndroid Build Coastguard Worker 
1375*2d543d20SAndroid Build Coastguard Worker 	args.flavor = CIL_TYPEPERMISSIVE;
1376*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = 0;
1377*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1378*2d543d20SAndroid Build Coastguard Worker 
1379*2d543d20SAndroid Build Coastguard Worker 	args.flavor = CIL_AVRULE;
1380*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_ALLOWED;
1381*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1382*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_AUDITALLOW;
1383*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1384*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_DONTAUDIT;
1385*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1386*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_NEVERALLOW;
1387*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1388*2d543d20SAndroid Build Coastguard Worker 
1389*2d543d20SAndroid Build Coastguard Worker 	args.flavor = CIL_AVRULEX;
1390*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_ALLOWED;
1391*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1392*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_AUDITALLOW;
1393*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1394*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_DONTAUDIT;
1395*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1396*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_NEVERALLOW;
1397*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1398*2d543d20SAndroid Build Coastguard Worker 
1399*2d543d20SAndroid Build Coastguard Worker 	args.flavor = CIL_TYPE_RULE;
1400*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_TYPE_TRANSITION;
1401*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1402*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_TYPE_MEMBER;
1403*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1404*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_TYPE_CHANGE;
1405*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1406*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = CIL_AVRULE_TYPE;
1407*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1408*2d543d20SAndroid Build Coastguard Worker 
1409*2d543d20SAndroid Build Coastguard Worker 	args.flavor = CIL_NAMETYPETRANSITION;
1410*2d543d20SAndroid Build Coastguard Worker 	args.rule_kind = 0;
1411*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1412*2d543d20SAndroid Build Coastguard Worker 
1413*2d543d20SAndroid Build Coastguard Worker 	if (mls == CIL_TRUE) {
1414*2d543d20SAndroid Build Coastguard Worker 		args.flavor = CIL_RANGETRANSITION;
1415*2d543d20SAndroid Build Coastguard Worker 		args.rule_kind = 0;
1416*2d543d20SAndroid Build Coastguard Worker 		cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
1417*2d543d20SAndroid Build Coastguard Worker 	}
1418*2d543d20SAndroid Build Coastguard Worker }
1419*2d543d20SAndroid Build Coastguard Worker 
1420*2d543d20SAndroid Build Coastguard Worker struct te_rules_extra {
1421*2d543d20SAndroid Build Coastguard Worker 	FILE *out;
1422*2d543d20SAndroid Build Coastguard Worker 	int mls;
1423*2d543d20SAndroid Build Coastguard Worker };
1424*2d543d20SAndroid Build Coastguard Worker 
__cil_te_rules_to_policy_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1425*2d543d20SAndroid Build Coastguard Worker static int __cil_te_rules_to_policy_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
1426*2d543d20SAndroid Build Coastguard Worker {
1427*2d543d20SAndroid Build Coastguard Worker 	struct te_rules_extra *args = extra_args;
1428*2d543d20SAndroid Build Coastguard Worker 
1429*2d543d20SAndroid Build Coastguard Worker 	switch (node->flavor) {
1430*2d543d20SAndroid Build Coastguard Worker 	case CIL_BLOCK: {
1431*2d543d20SAndroid Build Coastguard Worker 		struct cil_block *blk = node->data;
1432*2d543d20SAndroid Build Coastguard Worker 		if (blk->is_abstract == CIL_TRUE) {
1433*2d543d20SAndroid Build Coastguard Worker 			*finished = CIL_TREE_SKIP_HEAD;
1434*2d543d20SAndroid Build Coastguard Worker 		}
1435*2d543d20SAndroid Build Coastguard Worker 		break;
1436*2d543d20SAndroid Build Coastguard Worker 	}
1437*2d543d20SAndroid Build Coastguard Worker 	case CIL_MACRO:
1438*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
1439*2d543d20SAndroid Build Coastguard Worker 		break;
1440*2d543d20SAndroid Build Coastguard Worker 	case CIL_BOOLEANIF: {
1441*2d543d20SAndroid Build Coastguard Worker 		struct cil_booleanif *boolean = node->data;
1442*2d543d20SAndroid Build Coastguard Worker 		struct cil_tree_node *n;
1443*2d543d20SAndroid Build Coastguard Worker 		struct cil_condblock *cb;
1444*2d543d20SAndroid Build Coastguard Worker 
1445*2d543d20SAndroid Build Coastguard Worker 		fprintf(args->out, "if ");
1446*2d543d20SAndroid Build Coastguard Worker 		cil_cond_expr_to_policy(args->out, boolean->datum_expr, CIL_TRUE);
1447*2d543d20SAndroid Build Coastguard Worker 		fprintf(args->out," {\n");
1448*2d543d20SAndroid Build Coastguard Worker 		n = node->cl_head;
1449*2d543d20SAndroid Build Coastguard Worker 		cb = n != NULL ? n->data : NULL;
1450*2d543d20SAndroid Build Coastguard Worker 		if (cb && cb->flavor == CIL_CONDTRUE) {
1451*2d543d20SAndroid Build Coastguard Worker 			cil_block_te_rules_to_policy(args->out, n, args->mls);
1452*2d543d20SAndroid Build Coastguard Worker 			n = n->next;
1453*2d543d20SAndroid Build Coastguard Worker 			cb = n != NULL ? n->data : NULL;
1454*2d543d20SAndroid Build Coastguard Worker 		}
1455*2d543d20SAndroid Build Coastguard Worker 		if (cb && cb->flavor == CIL_CONDFALSE) {
1456*2d543d20SAndroid Build Coastguard Worker 			fprintf(args->out,"} else {\n");
1457*2d543d20SAndroid Build Coastguard Worker 			cil_block_te_rules_to_policy(args->out, n, args->mls);
1458*2d543d20SAndroid Build Coastguard Worker 		}
1459*2d543d20SAndroid Build Coastguard Worker 		fprintf(args->out,"}\n");
1460*2d543d20SAndroid Build Coastguard Worker 		*finished = CIL_TREE_SKIP_HEAD;
1461*2d543d20SAndroid Build Coastguard Worker 		break;
1462*2d543d20SAndroid Build Coastguard Worker 	}
1463*2d543d20SAndroid Build Coastguard Worker 	default:
1464*2d543d20SAndroid Build Coastguard Worker 		break;
1465*2d543d20SAndroid Build Coastguard Worker 	}
1466*2d543d20SAndroid Build Coastguard Worker 
1467*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_OK;
1468*2d543d20SAndroid Build Coastguard Worker }
1469*2d543d20SAndroid Build Coastguard Worker 
cil_te_rules_to_policy(FILE * out,struct cil_tree_node * head,int mls)1470*2d543d20SAndroid Build Coastguard Worker static void cil_te_rules_to_policy(FILE *out, struct cil_tree_node *head, int mls)
1471*2d543d20SAndroid Build Coastguard Worker {
1472*2d543d20SAndroid Build Coastguard Worker 	struct te_rules_extra args;
1473*2d543d20SAndroid Build Coastguard Worker 
1474*2d543d20SAndroid Build Coastguard Worker 	args.out = out;
1475*2d543d20SAndroid Build Coastguard Worker 	args.mls = mls;
1476*2d543d20SAndroid Build Coastguard Worker 
1477*2d543d20SAndroid Build Coastguard Worker 	cil_block_te_rules_to_policy(out, head, mls);
1478*2d543d20SAndroid Build Coastguard Worker 	cil_tree_walk(head, __cil_te_rules_to_policy_helper, NULL, NULL, &args);
1479*2d543d20SAndroid Build Coastguard Worker }
1480*2d543d20SAndroid Build Coastguard Worker 
cil_roles_to_policy(FILE * out,struct cil_list * rules)1481*2d543d20SAndroid Build Coastguard Worker static void cil_roles_to_policy(FILE *out, struct cil_list *rules)
1482*2d543d20SAndroid Build Coastguard Worker {
1483*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1484*2d543d20SAndroid Build Coastguard Worker 	struct cil_role *role;
1485*2d543d20SAndroid Build Coastguard Worker 
1486*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, rules) {
1487*2d543d20SAndroid Build Coastguard Worker 		role = i1->data;
1488*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(role->datum.fqn,"object_r") == 0)
1489*2d543d20SAndroid Build Coastguard Worker 			continue;
1490*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "role %s;\n", role->datum.fqn);
1491*2d543d20SAndroid Build Coastguard Worker 	}
1492*2d543d20SAndroid Build Coastguard Worker }
1493*2d543d20SAndroid Build Coastguard Worker 
cil_role_types_to_policy(FILE * out,struct cil_list * roles,struct cil_list * types)1494*2d543d20SAndroid Build Coastguard Worker static void cil_role_types_to_policy(FILE *out, struct cil_list *roles, struct cil_list *types)
1495*2d543d20SAndroid Build Coastguard Worker {
1496*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1497*2d543d20SAndroid Build Coastguard Worker 	struct cil_role *role;
1498*2d543d20SAndroid Build Coastguard Worker 	struct cil_type *type;
1499*2d543d20SAndroid Build Coastguard Worker 	int first = CIL_TRUE;
1500*2d543d20SAndroid Build Coastguard Worker 
1501*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, roles) {
1502*2d543d20SAndroid Build Coastguard Worker 		role = i1->data;
1503*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(role->datum.fqn,"object_r") == 0)
1504*2d543d20SAndroid Build Coastguard Worker 			continue;
1505*2d543d20SAndroid Build Coastguard Worker 		if (role->types) {
1506*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, types) {
1507*2d543d20SAndroid Build Coastguard Worker 				type = i2->data;
1508*2d543d20SAndroid Build Coastguard Worker 				if (ebitmap_get_bit(role->types, type->value)) {
1509*2d543d20SAndroid Build Coastguard Worker 					if (first) {
1510*2d543d20SAndroid Build Coastguard Worker 						fprintf(out, "role %s types { %s", role->datum.fqn, type->datum.fqn);
1511*2d543d20SAndroid Build Coastguard Worker 						first = CIL_FALSE;
1512*2d543d20SAndroid Build Coastguard Worker 					} else {
1513*2d543d20SAndroid Build Coastguard Worker 						fprintf(out, " %s", type->datum.fqn);
1514*2d543d20SAndroid Build Coastguard Worker 					}
1515*2d543d20SAndroid Build Coastguard Worker 				}
1516*2d543d20SAndroid Build Coastguard Worker 			}
1517*2d543d20SAndroid Build Coastguard Worker 			if (!first) {
1518*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " }");
1519*2d543d20SAndroid Build Coastguard Worker 				first = CIL_TRUE;
1520*2d543d20SAndroid Build Coastguard Worker 			}
1521*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, ";\n");
1522*2d543d20SAndroid Build Coastguard Worker 		}
1523*2d543d20SAndroid Build Coastguard Worker 	}
1524*2d543d20SAndroid Build Coastguard Worker }
1525*2d543d20SAndroid Build Coastguard Worker 
cil_roleattributes_to_policy(FILE * out,struct cil_list * roles,struct cil_list * attributes)1526*2d543d20SAndroid Build Coastguard Worker static void cil_roleattributes_to_policy(FILE *out, struct cil_list *roles, struct cil_list *attributes)
1527*2d543d20SAndroid Build Coastguard Worker {
1528*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1529*2d543d20SAndroid Build Coastguard Worker 	struct cil_role *role;
1530*2d543d20SAndroid Build Coastguard Worker 	struct cil_roleattribute *attribute;
1531*2d543d20SAndroid Build Coastguard Worker 	int first = CIL_TRUE;
1532*2d543d20SAndroid Build Coastguard Worker 
1533*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, roles) {
1534*2d543d20SAndroid Build Coastguard Worker 		role = i1->data;
1535*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(role->datum.fqn,"object_r") == 0)
1536*2d543d20SAndroid Build Coastguard Worker 			continue;
1537*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, attributes) {
1538*2d543d20SAndroid Build Coastguard Worker 			attribute = i2->data;
1539*2d543d20SAndroid Build Coastguard Worker 			if (ebitmap_get_bit(attribute->roles, role->value)) {
1540*2d543d20SAndroid Build Coastguard Worker 				if (first) {
1541*2d543d20SAndroid Build Coastguard Worker 					fprintf(out, "roleattribute %s %s", role->datum.fqn, attribute->datum.fqn);
1542*2d543d20SAndroid Build Coastguard Worker 					first = CIL_FALSE;
1543*2d543d20SAndroid Build Coastguard Worker 				} else {
1544*2d543d20SAndroid Build Coastguard Worker 					fprintf(out, ", %s", attribute->datum.fqn);
1545*2d543d20SAndroid Build Coastguard Worker 				}
1546*2d543d20SAndroid Build Coastguard Worker 			}
1547*2d543d20SAndroid Build Coastguard Worker 		}
1548*2d543d20SAndroid Build Coastguard Worker 		if (!first) {
1549*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, ";\n");
1550*2d543d20SAndroid Build Coastguard Worker 			first = CIL_TRUE;
1551*2d543d20SAndroid Build Coastguard Worker 		}
1552*2d543d20SAndroid Build Coastguard Worker 	}
1553*2d543d20SAndroid Build Coastguard Worker }
1554*2d543d20SAndroid Build Coastguard Worker 
cil_roleallows_to_policy(FILE * out,struct cil_list * roleallows)1555*2d543d20SAndroid Build Coastguard Worker static void cil_roleallows_to_policy(FILE *out, struct cil_list *roleallows)
1556*2d543d20SAndroid Build Coastguard Worker {
1557*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1558*2d543d20SAndroid Build Coastguard Worker 	struct cil_roleallow *allow;
1559*2d543d20SAndroid Build Coastguard Worker 
1560*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, roleallows) {
1561*2d543d20SAndroid Build Coastguard Worker 		allow = i1->data;
1562*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "allow %s %s;\n", DATUM(allow->src)->fqn, DATUM(allow->tgt)->fqn);
1563*2d543d20SAndroid Build Coastguard Worker 	}
1564*2d543d20SAndroid Build Coastguard Worker }
1565*2d543d20SAndroid Build Coastguard Worker 
cil_roletransitions_to_policy(FILE * out,struct cil_list * roletransitions)1566*2d543d20SAndroid Build Coastguard Worker static void cil_roletransitions_to_policy(FILE *out, struct cil_list *roletransitions)
1567*2d543d20SAndroid Build Coastguard Worker {
1568*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1569*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *class_list;
1570*2d543d20SAndroid Build Coastguard Worker 	struct cil_roletransition *trans;
1571*2d543d20SAndroid Build Coastguard Worker 
1572*2d543d20SAndroid Build Coastguard Worker 
1573*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, roletransitions) {
1574*2d543d20SAndroid Build Coastguard Worker 		trans = i1->data;
1575*2d543d20SAndroid Build Coastguard Worker 		class_list = cil_expand_class(trans->obj);
1576*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, class_list) {
1577*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "role_transition %s %s : %s %s;\n", DATUM(trans->src)->fqn, DATUM(trans->tgt)->fqn, DATUM(i2->data)->fqn, DATUM(trans->result)->fqn);
1578*2d543d20SAndroid Build Coastguard Worker 		}
1579*2d543d20SAndroid Build Coastguard Worker 		cil_list_destroy(&class_list, CIL_FALSE);
1580*2d543d20SAndroid Build Coastguard Worker 	}
1581*2d543d20SAndroid Build Coastguard Worker }
1582*2d543d20SAndroid Build Coastguard Worker 
cil_users_to_policy(FILE * out,int mls,struct cil_list * users,struct cil_list * all_roles)1583*2d543d20SAndroid Build Coastguard Worker static void cil_users_to_policy(FILE *out, int mls, struct cil_list *users, struct cil_list *all_roles)
1584*2d543d20SAndroid Build Coastguard Worker {
1585*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1586*2d543d20SAndroid Build Coastguard Worker 	struct cil_user *user;
1587*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *roles = NULL;
1588*2d543d20SAndroid Build Coastguard Worker 	struct cil_role *role;
1589*2d543d20SAndroid Build Coastguard Worker 	int num_roles;
1590*2d543d20SAndroid Build Coastguard Worker 
1591*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, users) {
1592*2d543d20SAndroid Build Coastguard Worker 		user = i1->data;
1593*2d543d20SAndroid Build Coastguard Worker 		num_roles = 0;
1594*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "user %s",user->datum.fqn);
1595*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, all_roles) {
1596*2d543d20SAndroid Build Coastguard Worker 			role = i2->data;
1597*2d543d20SAndroid Build Coastguard Worker 			if (ebitmap_get_bit(user->roles, role->value)) {
1598*2d543d20SAndroid Build Coastguard Worker 				if (num_roles == 0) {
1599*2d543d20SAndroid Build Coastguard Worker 					cil_list_init(&roles, CIL_LIST);
1600*2d543d20SAndroid Build Coastguard Worker 				}
1601*2d543d20SAndroid Build Coastguard Worker 				cil_list_append(roles, CIL_ROLE, role);
1602*2d543d20SAndroid Build Coastguard Worker 				num_roles++;
1603*2d543d20SAndroid Build Coastguard Worker 			}
1604*2d543d20SAndroid Build Coastguard Worker 		}
1605*2d543d20SAndroid Build Coastguard Worker 		if (num_roles > 0) {
1606*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " roles");
1607*2d543d20SAndroid Build Coastguard Worker 			if (num_roles > 1) {
1608*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " {");
1609*2d543d20SAndroid Build Coastguard Worker 			}
1610*2d543d20SAndroid Build Coastguard Worker 			cil_list_for_each(i2, roles) {
1611*2d543d20SAndroid Build Coastguard Worker 				role = i2->data;
1612*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " %s", role->datum.fqn);
1613*2d543d20SAndroid Build Coastguard Worker 			}
1614*2d543d20SAndroid Build Coastguard Worker 			if (num_roles > 1) {
1615*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, " }");
1616*2d543d20SAndroid Build Coastguard Worker 			}
1617*2d543d20SAndroid Build Coastguard Worker 			cil_list_destroy(&roles, CIL_FALSE);
1618*2d543d20SAndroid Build Coastguard Worker 		}
1619*2d543d20SAndroid Build Coastguard Worker 
1620*2d543d20SAndroid Build Coastguard Worker 		if (mls == CIL_TRUE && user->dftlevel != NULL) {
1621*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " level ");
1622*2d543d20SAndroid Build Coastguard Worker 			cil_level_to_policy(out, user->dftlevel);
1623*2d543d20SAndroid Build Coastguard Worker 		}
1624*2d543d20SAndroid Build Coastguard Worker 
1625*2d543d20SAndroid Build Coastguard Worker 		if (mls == CIL_TRUE && user->range != NULL) {
1626*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, " range ");
1627*2d543d20SAndroid Build Coastguard Worker 			cil_levelrange_to_policy(out, user->range);
1628*2d543d20SAndroid Build Coastguard Worker 		}
1629*2d543d20SAndroid Build Coastguard Worker 
1630*2d543d20SAndroid Build Coastguard Worker 		fprintf(out,";\n");
1631*2d543d20SAndroid Build Coastguard Worker 	}
1632*2d543d20SAndroid Build Coastguard Worker }
1633*2d543d20SAndroid Build Coastguard Worker 
cil_constrains_to_policy(FILE * out,struct cil_db * db,struct cil_list * constrains)1634*2d543d20SAndroid Build Coastguard Worker static void cil_constrains_to_policy(FILE *out, struct cil_db *db, struct cil_list *constrains)
1635*2d543d20SAndroid Build Coastguard Worker {
1636*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1, *i2;
1637*2d543d20SAndroid Build Coastguard Worker 	struct cil_constrain *cons;
1638*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *classperms_strs;
1639*2d543d20SAndroid Build Coastguard Worker 	char *cp_str;
1640*2d543d20SAndroid Build Coastguard Worker 	char *expr_str;
1641*2d543d20SAndroid Build Coastguard Worker 
1642*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, constrains) {
1643*2d543d20SAndroid Build Coastguard Worker 		cons = i1->data;
1644*2d543d20SAndroid Build Coastguard Worker 		cil_list_init(&classperms_strs, CIL_LIST);
1645*2d543d20SAndroid Build Coastguard Worker 		cil_classperms_to_strings(cons->classperms, classperms_strs);
1646*2d543d20SAndroid Build Coastguard Worker 		expr_str = cil_cons_expr_to_string(db, cons->datum_expr);
1647*2d543d20SAndroid Build Coastguard Worker 		cil_list_for_each(i2, classperms_strs) {
1648*2d543d20SAndroid Build Coastguard Worker 			cp_str = i2->data;
1649*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "constrain %s %s;\n",cp_str, expr_str);
1650*2d543d20SAndroid Build Coastguard Worker 			free(cp_str);
1651*2d543d20SAndroid Build Coastguard Worker 		}
1652*2d543d20SAndroid Build Coastguard Worker 		free(expr_str);
1653*2d543d20SAndroid Build Coastguard Worker 		cil_list_destroy(&classperms_strs, CIL_FALSE);
1654*2d543d20SAndroid Build Coastguard Worker 	}
1655*2d543d20SAndroid Build Coastguard Worker }
1656*2d543d20SAndroid Build Coastguard Worker 
cil_sid_contexts_to_policy(FILE * out,struct cil_list * sids,int mls)1657*2d543d20SAndroid Build Coastguard Worker static void cil_sid_contexts_to_policy(FILE *out, struct cil_list *sids, int mls)
1658*2d543d20SAndroid Build Coastguard Worker {
1659*2d543d20SAndroid Build Coastguard Worker 	struct cil_list_item *i1;
1660*2d543d20SAndroid Build Coastguard Worker 	struct cil_sid *sid;
1661*2d543d20SAndroid Build Coastguard Worker 
1662*2d543d20SAndroid Build Coastguard Worker 	cil_list_for_each(i1, sids) {
1663*2d543d20SAndroid Build Coastguard Worker 		sid = i1->data;
1664*2d543d20SAndroid Build Coastguard Worker 		if (sid->context) {
1665*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "sid %s ", sid->datum.fqn);
1666*2d543d20SAndroid Build Coastguard Worker 			cil_context_to_policy(out, sid->context, mls);
1667*2d543d20SAndroid Build Coastguard Worker 			fprintf(out,"\n");
1668*2d543d20SAndroid Build Coastguard Worker 		}
1669*2d543d20SAndroid Build Coastguard Worker 	}
1670*2d543d20SAndroid Build Coastguard Worker }
1671*2d543d20SAndroid Build Coastguard Worker 
cil_fsuses_to_policy(FILE * out,struct cil_sort * fsuses,int mls)1672*2d543d20SAndroid Build Coastguard Worker static void cil_fsuses_to_policy(FILE *out, struct cil_sort *fsuses, int mls)
1673*2d543d20SAndroid Build Coastguard Worker {
1674*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1675*2d543d20SAndroid Build Coastguard Worker 	struct cil_fsuse *fsuse;
1676*2d543d20SAndroid Build Coastguard Worker 
1677*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<fsuses->count; i++) {
1678*2d543d20SAndroid Build Coastguard Worker 		fsuse = fsuses->array[i];
1679*2d543d20SAndroid Build Coastguard Worker 		if (fsuse->type == CIL_FSUSE_XATTR) {
1680*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "fs_use_xattr %s ", fsuse->fs_str);
1681*2d543d20SAndroid Build Coastguard Worker 			cil_context_to_policy(out, fsuse->context, mls);
1682*2d543d20SAndroid Build Coastguard Worker 			fprintf(out,";\n");
1683*2d543d20SAndroid Build Coastguard Worker 		}
1684*2d543d20SAndroid Build Coastguard Worker 	}
1685*2d543d20SAndroid Build Coastguard Worker 
1686*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<fsuses->count; i++) {
1687*2d543d20SAndroid Build Coastguard Worker 		fsuse = fsuses->array[i];
1688*2d543d20SAndroid Build Coastguard Worker 		if (fsuse->type == CIL_FSUSE_TASK) {
1689*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "fs_use_task %s ", fsuse->fs_str);
1690*2d543d20SAndroid Build Coastguard Worker 			cil_context_to_policy(out, fsuse->context, mls);
1691*2d543d20SAndroid Build Coastguard Worker 			fprintf(out,";\n");
1692*2d543d20SAndroid Build Coastguard Worker 		}
1693*2d543d20SAndroid Build Coastguard Worker 	}
1694*2d543d20SAndroid Build Coastguard Worker 
1695*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<fsuses->count; i++) {
1696*2d543d20SAndroid Build Coastguard Worker 		fsuse = fsuses->array[i];
1697*2d543d20SAndroid Build Coastguard Worker 		if (fsuse->type == CIL_FSUSE_TRANS) {
1698*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "fs_use_trans %s ", fsuse->fs_str);
1699*2d543d20SAndroid Build Coastguard Worker 			cil_context_to_policy(out, fsuse->context, mls);
1700*2d543d20SAndroid Build Coastguard Worker 			fprintf(out,";\n");
1701*2d543d20SAndroid Build Coastguard Worker 		}
1702*2d543d20SAndroid Build Coastguard Worker 	}
1703*2d543d20SAndroid Build Coastguard Worker }
1704*2d543d20SAndroid Build Coastguard Worker 
cil_genfscons_to_policy(FILE * out,struct cil_sort * genfscons,int mls)1705*2d543d20SAndroid Build Coastguard Worker static void cil_genfscons_to_policy(FILE *out, struct cil_sort *genfscons, int mls)
1706*2d543d20SAndroid Build Coastguard Worker {
1707*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1708*2d543d20SAndroid Build Coastguard Worker 	struct cil_genfscon *genfscon;
1709*2d543d20SAndroid Build Coastguard Worker 
1710*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<genfscons->count; i++) {
1711*2d543d20SAndroid Build Coastguard Worker 		genfscon = genfscons->array[i];
1712*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "genfscon %s %s ", genfscon->fs_str, genfscon->path_str);
1713*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, genfscon->context, mls);
1714*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1715*2d543d20SAndroid Build Coastguard Worker 	}
1716*2d543d20SAndroid Build Coastguard Worker }
1717*2d543d20SAndroid Build Coastguard Worker 
cil_ibpkeycons_to_policy(FILE * out,struct cil_sort * ibpkeycons,int mls)1718*2d543d20SAndroid Build Coastguard Worker static void cil_ibpkeycons_to_policy(FILE *out, struct cil_sort *ibpkeycons, int mls)
1719*2d543d20SAndroid Build Coastguard Worker {
1720*2d543d20SAndroid Build Coastguard Worker 	uint32_t i = 0;
1721*2d543d20SAndroid Build Coastguard Worker 
1722*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ibpkeycons->count; i++) {
1723*2d543d20SAndroid Build Coastguard Worker 		struct cil_ibpkeycon *ibpkeycon = (struct cil_ibpkeycon *)ibpkeycons->array[i];
1724*2d543d20SAndroid Build Coastguard Worker 
1725*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "ibpkeycon %s ", ibpkeycon->subnet_prefix_str);
1726*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%d ", ibpkeycon->pkey_low);
1727*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%d ", ibpkeycon->pkey_high);
1728*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, ibpkeycon->context, mls);
1729*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1730*2d543d20SAndroid Build Coastguard Worker 	}
1731*2d543d20SAndroid Build Coastguard Worker }
1732*2d543d20SAndroid Build Coastguard Worker 
cil_ibendportcons_to_policy(FILE * out,struct cil_sort * ibendportcons,int mls)1733*2d543d20SAndroid Build Coastguard Worker static void cil_ibendportcons_to_policy(FILE *out, struct cil_sort *ibendportcons, int mls)
1734*2d543d20SAndroid Build Coastguard Worker {
1735*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
1736*2d543d20SAndroid Build Coastguard Worker 
1737*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ibendportcons->count; i++) {
1738*2d543d20SAndroid Build Coastguard Worker 		struct cil_ibendportcon *ibendportcon = (struct cil_ibendportcon *)ibendportcons->array[i];
1739*2d543d20SAndroid Build Coastguard Worker 
1740*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "ibendportcon %s ", ibendportcon->dev_name_str);
1741*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "%u ", ibendportcon->port);
1742*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, ibendportcon->context, mls);
1743*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1744*2d543d20SAndroid Build Coastguard Worker 	}
1745*2d543d20SAndroid Build Coastguard Worker }
1746*2d543d20SAndroid Build Coastguard Worker 
cil_portcons_to_policy(FILE * out,struct cil_sort * portcons,int mls)1747*2d543d20SAndroid Build Coastguard Worker static void cil_portcons_to_policy(FILE *out, struct cil_sort *portcons, int mls)
1748*2d543d20SAndroid Build Coastguard Worker {
1749*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1750*2d543d20SAndroid Build Coastguard Worker 	struct cil_portcon *portcon;
1751*2d543d20SAndroid Build Coastguard Worker 
1752*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<portcons->count; i++) {
1753*2d543d20SAndroid Build Coastguard Worker 		portcon = portcons->array[i];
1754*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "portcon ");
1755*2d543d20SAndroid Build Coastguard Worker 		if (portcon->proto == CIL_PROTOCOL_UDP) {
1756*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "udp ");
1757*2d543d20SAndroid Build Coastguard Worker 		} else if (portcon->proto == CIL_PROTOCOL_TCP) {
1758*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "tcp ");
1759*2d543d20SAndroid Build Coastguard Worker 		} else if (portcon->proto == CIL_PROTOCOL_DCCP) {
1760*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "dccp ");
1761*2d543d20SAndroid Build Coastguard Worker 		} else if (portcon->proto == CIL_PROTOCOL_SCTP) {
1762*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "sctp ");
1763*2d543d20SAndroid Build Coastguard Worker 		}
1764*2d543d20SAndroid Build Coastguard Worker 		if (portcon->port_low == portcon->port_high) {
1765*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%d ", portcon->port_low);
1766*2d543d20SAndroid Build Coastguard Worker 		} else {
1767*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "%d-%d ", portcon->port_low, portcon->port_high);
1768*2d543d20SAndroid Build Coastguard Worker 		}
1769*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, portcon->context, mls);
1770*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1771*2d543d20SAndroid Build Coastguard Worker 	}
1772*2d543d20SAndroid Build Coastguard Worker }
1773*2d543d20SAndroid Build Coastguard Worker 
cil_netifcons_to_policy(FILE * out,struct cil_sort * netifcons,int mls)1774*2d543d20SAndroid Build Coastguard Worker static void cil_netifcons_to_policy(FILE *out, struct cil_sort *netifcons, int mls)
1775*2d543d20SAndroid Build Coastguard Worker {
1776*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1777*2d543d20SAndroid Build Coastguard Worker 	struct cil_netifcon *netifcon;
1778*2d543d20SAndroid Build Coastguard Worker 
1779*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<netifcons->count; i++) {
1780*2d543d20SAndroid Build Coastguard Worker 		netifcon = netifcons->array[i];
1781*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "netifcon %s ", netifcon->interface_str);
1782*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, netifcon->if_context, mls);
1783*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, " ");
1784*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, netifcon->packet_context, mls);
1785*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1786*2d543d20SAndroid Build Coastguard Worker 	}
1787*2d543d20SAndroid Build Coastguard Worker }
1788*2d543d20SAndroid Build Coastguard Worker 
cil_nodecons_to_policy(FILE * out,struct cil_sort * nodecons,int mls)1789*2d543d20SAndroid Build Coastguard Worker static void cil_nodecons_to_policy(FILE *out, struct cil_sort *nodecons, int mls)
1790*2d543d20SAndroid Build Coastguard Worker {
1791*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1792*2d543d20SAndroid Build Coastguard Worker 	struct cil_nodecon *nodecon;
1793*2d543d20SAndroid Build Coastguard Worker 	char *addr, *mask;
1794*2d543d20SAndroid Build Coastguard Worker 
1795*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<nodecons->count; i++) {
1796*2d543d20SAndroid Build Coastguard Worker 		nodecon = nodecons->array[i];
1797*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "nodecon ");
1798*2d543d20SAndroid Build Coastguard Worker 
1799*2d543d20SAndroid Build Coastguard Worker 		if (nodecon->addr->family == AF_INET) {
1800*2d543d20SAndroid Build Coastguard Worker 			errno = 0;
1801*2d543d20SAndroid Build Coastguard Worker 			addr = cil_malloc(INET_ADDRSTRLEN);
1802*2d543d20SAndroid Build Coastguard Worker 			inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v4, addr, INET_ADDRSTRLEN);
1803*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0) {
1804*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "%s ",addr);
1805*2d543d20SAndroid Build Coastguard Worker 			} else {
1806*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "[INVALID] ");
1807*2d543d20SAndroid Build Coastguard Worker 			}
1808*2d543d20SAndroid Build Coastguard Worker 			free(addr);
1809*2d543d20SAndroid Build Coastguard Worker 
1810*2d543d20SAndroid Build Coastguard Worker 			errno = 0;
1811*2d543d20SAndroid Build Coastguard Worker 			mask = cil_malloc(INET_ADDRSTRLEN);
1812*2d543d20SAndroid Build Coastguard Worker 			inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v4, mask, INET_ADDRSTRLEN);
1813*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0) {
1814*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "%s ",mask);
1815*2d543d20SAndroid Build Coastguard Worker 			} else {
1816*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "[INVALID] ");
1817*2d543d20SAndroid Build Coastguard Worker 			}
1818*2d543d20SAndroid Build Coastguard Worker 			free(mask);
1819*2d543d20SAndroid Build Coastguard Worker 		} else {
1820*2d543d20SAndroid Build Coastguard Worker 			errno = 0;
1821*2d543d20SAndroid Build Coastguard Worker 			addr = cil_malloc(INET6_ADDRSTRLEN);
1822*2d543d20SAndroid Build Coastguard Worker 			inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v6, addr, INET6_ADDRSTRLEN);
1823*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0) {
1824*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "%s ",addr);
1825*2d543d20SAndroid Build Coastguard Worker 			} else {
1826*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "[INVALID] ");
1827*2d543d20SAndroid Build Coastguard Worker 			}
1828*2d543d20SAndroid Build Coastguard Worker 			free(addr);
1829*2d543d20SAndroid Build Coastguard Worker 
1830*2d543d20SAndroid Build Coastguard Worker 			errno = 0;
1831*2d543d20SAndroid Build Coastguard Worker 			mask = cil_malloc(INET6_ADDRSTRLEN);
1832*2d543d20SAndroid Build Coastguard Worker 			inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v6, mask, INET6_ADDRSTRLEN);
1833*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0) {
1834*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "%s ",mask);
1835*2d543d20SAndroid Build Coastguard Worker 			} else {
1836*2d543d20SAndroid Build Coastguard Worker 				fprintf(out, "[INVALID] ");
1837*2d543d20SAndroid Build Coastguard Worker 			}
1838*2d543d20SAndroid Build Coastguard Worker 			free(mask);
1839*2d543d20SAndroid Build Coastguard Worker 		}
1840*2d543d20SAndroid Build Coastguard Worker 
1841*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, nodecon->context, mls);
1842*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "\n");
1843*2d543d20SAndroid Build Coastguard Worker 	}
1844*2d543d20SAndroid Build Coastguard Worker }
1845*2d543d20SAndroid Build Coastguard Worker 
cil_pirqcons_to_policy(FILE * out,struct cil_sort * pirqcons,int mls)1846*2d543d20SAndroid Build Coastguard Worker static void cil_pirqcons_to_policy(FILE *out, struct cil_sort *pirqcons, int mls)
1847*2d543d20SAndroid Build Coastguard Worker {
1848*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1849*2d543d20SAndroid Build Coastguard Worker 	struct cil_pirqcon *pirqcon;
1850*2d543d20SAndroid Build Coastguard Worker 
1851*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i<pirqcons->count; i++) {
1852*2d543d20SAndroid Build Coastguard Worker 		pirqcon = pirqcons->array[i];
1853*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "pirqcon %d ", pirqcon->pirq);
1854*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, pirqcon->context, mls);
1855*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1856*2d543d20SAndroid Build Coastguard Worker 	}
1857*2d543d20SAndroid Build Coastguard Worker }
1858*2d543d20SAndroid Build Coastguard Worker 
cil_iomemcons_to_policy(FILE * out,struct cil_sort * iomemcons,int mls)1859*2d543d20SAndroid Build Coastguard Worker static void cil_iomemcons_to_policy(FILE *out, struct cil_sort *iomemcons, int mls)
1860*2d543d20SAndroid Build Coastguard Worker {
1861*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1862*2d543d20SAndroid Build Coastguard Worker 	struct cil_iomemcon *iomemcon;
1863*2d543d20SAndroid Build Coastguard Worker 
1864*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i<iomemcons->count; i++) {
1865*2d543d20SAndroid Build Coastguard Worker 		iomemcon = iomemcons->array[i];
1866*2d543d20SAndroid Build Coastguard Worker 		if (iomemcon->iomem_low == iomemcon->iomem_high) {
1867*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "iomemcon %"PRIx64" ", iomemcon->iomem_low);
1868*2d543d20SAndroid Build Coastguard Worker 		} else {
1869*2d543d20SAndroid Build Coastguard Worker 			fprintf(out, "iomemcon %"PRIx64"-%"PRIx64" ", iomemcon->iomem_low, iomemcon->iomem_high);
1870*2d543d20SAndroid Build Coastguard Worker 		}
1871*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, iomemcon->context, mls);
1872*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1873*2d543d20SAndroid Build Coastguard Worker 	}
1874*2d543d20SAndroid Build Coastguard Worker }
1875*2d543d20SAndroid Build Coastguard Worker 
cil_ioportcons_to_policy(FILE * out,struct cil_sort * ioportcons,int mls)1876*2d543d20SAndroid Build Coastguard Worker static void cil_ioportcons_to_policy(FILE *out, struct cil_sort *ioportcons, int mls)
1877*2d543d20SAndroid Build Coastguard Worker {
1878*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1879*2d543d20SAndroid Build Coastguard Worker 	struct cil_ioportcon *ioportcon;
1880*2d543d20SAndroid Build Coastguard Worker 
1881*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ioportcons->count; i++) {
1882*2d543d20SAndroid Build Coastguard Worker 		ioportcon = ioportcons->array[i];
1883*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "ioportcon 0x%x-0x%x ", ioportcon->ioport_low, ioportcon->ioport_high);
1884*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, ioportcon->context, mls);
1885*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1886*2d543d20SAndroid Build Coastguard Worker 	}
1887*2d543d20SAndroid Build Coastguard Worker }
1888*2d543d20SAndroid Build Coastguard Worker 
cil_pcidevicecons_to_policy(FILE * out,struct cil_sort * pcidevicecons,int mls)1889*2d543d20SAndroid Build Coastguard Worker static void cil_pcidevicecons_to_policy(FILE *out, struct cil_sort *pcidevicecons, int mls)
1890*2d543d20SAndroid Build Coastguard Worker {
1891*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1892*2d543d20SAndroid Build Coastguard Worker 	struct cil_pcidevicecon *pcidevicecon;
1893*2d543d20SAndroid Build Coastguard Worker 
1894*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < pcidevicecons->count; i++) {
1895*2d543d20SAndroid Build Coastguard Worker 		pcidevicecon = pcidevicecons->array[i];
1896*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "pcidevicecon 0x%x ", pcidevicecon->dev);
1897*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, pcidevicecon->context, mls);
1898*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1899*2d543d20SAndroid Build Coastguard Worker 	}
1900*2d543d20SAndroid Build Coastguard Worker }
1901*2d543d20SAndroid Build Coastguard Worker 
cil_devicetreecons_to_policy(FILE * out,struct cil_sort * devicetreecons,int mls)1902*2d543d20SAndroid Build Coastguard Worker static void cil_devicetreecons_to_policy(FILE *out, struct cil_sort *devicetreecons, int mls)
1903*2d543d20SAndroid Build Coastguard Worker {
1904*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1905*2d543d20SAndroid Build Coastguard Worker 	struct cil_devicetreecon *devicetreecon;
1906*2d543d20SAndroid Build Coastguard Worker 
1907*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < devicetreecons->count; i++) {
1908*2d543d20SAndroid Build Coastguard Worker 		devicetreecon = devicetreecons->array[i];
1909*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, "devicetreecon %s ", devicetreecon->path);
1910*2d543d20SAndroid Build Coastguard Worker 		cil_context_to_policy(out, devicetreecon->context, mls);
1911*2d543d20SAndroid Build Coastguard Worker 		fprintf(out, ";\n");
1912*2d543d20SAndroid Build Coastguard Worker 	}
1913*2d543d20SAndroid Build Coastguard Worker }
1914*2d543d20SAndroid Build Coastguard Worker 
cil_gen_policy(FILE * out,struct cil_db * db)1915*2d543d20SAndroid Build Coastguard Worker void cil_gen_policy(FILE *out, struct cil_db *db)
1916*2d543d20SAndroid Build Coastguard Worker {
1917*2d543d20SAndroid Build Coastguard Worker 	unsigned i;
1918*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *head = db->ast->root;
1919*2d543d20SAndroid Build Coastguard Worker 	struct cil_list *lists[CIL_LIST_NUM_LISTS];
1920*2d543d20SAndroid Build Coastguard Worker 
1921*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<CIL_LIST_NUM_LISTS; i++) {
1922*2d543d20SAndroid Build Coastguard Worker 		cil_list_init(&lists[i], CIL_LIST);
1923*2d543d20SAndroid Build Coastguard Worker 	}
1924*2d543d20SAndroid Build Coastguard Worker 
1925*2d543d20SAndroid Build Coastguard Worker 	cil_gather_statements(head, lists);
1926*2d543d20SAndroid Build Coastguard Worker 
1927*2d543d20SAndroid Build Coastguard Worker 	cil_class_decls_to_policy(out, db->classorder);
1928*2d543d20SAndroid Build Coastguard Worker 
1929*2d543d20SAndroid Build Coastguard Worker 	cil_sid_decls_to_policy(out, db->sidorder);
1930*2d543d20SAndroid Build Coastguard Worker 
1931*2d543d20SAndroid Build Coastguard Worker 	cil_commons_to_policy(out, lists[CIL_LIST_COMMON]);
1932*2d543d20SAndroid Build Coastguard Worker 	cil_classes_to_policy(out, db->classorder);
1933*2d543d20SAndroid Build Coastguard Worker 
1934*2d543d20SAndroid Build Coastguard Worker 	cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], "default_user");
1935*2d543d20SAndroid Build Coastguard Worker 	cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], "default_role");
1936*2d543d20SAndroid Build Coastguard Worker 	cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], "default_type");
1937*2d543d20SAndroid Build Coastguard Worker 
1938*2d543d20SAndroid Build Coastguard Worker 	if (db->mls == CIL_TRUE) {
1939*2d543d20SAndroid Build Coastguard Worker 		cil_default_ranges_to_policy(out, lists[CIL_LIST_DEFAULT_RANGE]);
1940*2d543d20SAndroid Build Coastguard Worker 		cil_sensitivities_to_policy(out, db->sensitivityorder, lists[CIL_LIST_SENSALIAS]);
1941*2d543d20SAndroid Build Coastguard Worker 		cil_dominance_to_policy(out, db->sensitivityorder);
1942*2d543d20SAndroid Build Coastguard Worker 		cil_categories_to_policy(out, db->catorder, lists[CIL_LIST_CATALIAS]);
1943*2d543d20SAndroid Build Coastguard Worker 		cil_levels_to_policy(out, db->sensitivityorder);
1944*2d543d20SAndroid Build Coastguard Worker 		cil_mlsconstrains_to_policy(out, db, lists[CIL_LIST_MLSCONSTRAIN]);
1945*2d543d20SAndroid Build Coastguard Worker 		cil_validatetrans_to_policy(out, db, lists[CIL_LIST_MLSVALIDATETRANS], CIL_KEY_MLSVALIDATETRANS);
1946*2d543d20SAndroid Build Coastguard Worker 	}
1947*2d543d20SAndroid Build Coastguard Worker 
1948*2d543d20SAndroid Build Coastguard Worker 	cil_simple_rules_to_policy(out, lists[CIL_LIST_POLICYCAP], CIL_KEY_POLICYCAP);
1949*2d543d20SAndroid Build Coastguard Worker 
1950*2d543d20SAndroid Build Coastguard Worker 	cil_simple_rules_to_policy(out, lists[CIL_LIST_TYPEATTRIBUTE], "attribute");
1951*2d543d20SAndroid Build Coastguard Worker 	cil_simple_rules_to_policy(out, lists[CIL_LIST_ROLEATTRIBUTE], "attribute_role");
1952*2d543d20SAndroid Build Coastguard Worker 
1953*2d543d20SAndroid Build Coastguard Worker 	cil_bools_to_policy(out, lists[CIL_LIST_BOOL]);
1954*2d543d20SAndroid Build Coastguard Worker 
1955*2d543d20SAndroid Build Coastguard Worker 	cil_simple_rules_to_policy(out, lists[CIL_LIST_TYPE], "type");
1956*2d543d20SAndroid Build Coastguard Worker 	cil_typealiases_to_policy(out, lists[CIL_LIST_TYPE], lists[CIL_LIST_TYPEALIAS]);
1957*2d543d20SAndroid Build Coastguard Worker 	cil_typebounds_to_policy(out, lists[CIL_LIST_TYPE]);
1958*2d543d20SAndroid Build Coastguard Worker 	cil_typeattributes_to_policy(out, lists[CIL_LIST_TYPE], lists[CIL_LIST_TYPEATTRIBUTE]);
1959*2d543d20SAndroid Build Coastguard Worker 	cil_te_rules_to_policy(out, head, db->mls);
1960*2d543d20SAndroid Build Coastguard Worker 
1961*2d543d20SAndroid Build Coastguard Worker 	cil_roles_to_policy(out, lists[CIL_LIST_ROLE]);
1962*2d543d20SAndroid Build Coastguard Worker 	cil_role_types_to_policy(out, lists[CIL_LIST_ROLE], lists[CIL_LIST_TYPE]);
1963*2d543d20SAndroid Build Coastguard Worker 	cil_roleattributes_to_policy(out, lists[CIL_LIST_ROLE], lists[CIL_LIST_ROLEATTRIBUTE]);
1964*2d543d20SAndroid Build Coastguard Worker 	cil_roleallows_to_policy(out, lists[CIL_LIST_ROLEALLOW]);
1965*2d543d20SAndroid Build Coastguard Worker 	cil_roletransitions_to_policy(out, lists[CIL_LIST_ROLETRANSITION]);
1966*2d543d20SAndroid Build Coastguard Worker 
1967*2d543d20SAndroid Build Coastguard Worker 	cil_users_to_policy(out, db->mls, lists[CIL_LIST_USER], lists[CIL_LIST_ROLE]);
1968*2d543d20SAndroid Build Coastguard Worker 
1969*2d543d20SAndroid Build Coastguard Worker 	cil_constrains_to_policy(out, db, lists[CIL_LIST_CONSTRAINT]);
1970*2d543d20SAndroid Build Coastguard Worker 	cil_validatetrans_to_policy(out, db, lists[CIL_LIST_VALIDATETRANS], CIL_KEY_VALIDATETRANS);
1971*2d543d20SAndroid Build Coastguard Worker 
1972*2d543d20SAndroid Build Coastguard Worker 	cil_sid_contexts_to_policy(out, db->sidorder, db->mls);
1973*2d543d20SAndroid Build Coastguard Worker 	cil_fsuses_to_policy(out, db->fsuse, db->mls);
1974*2d543d20SAndroid Build Coastguard Worker 	cil_genfscons_to_policy(out, db->genfscon, db->mls);
1975*2d543d20SAndroid Build Coastguard Worker 	cil_portcons_to_policy(out, db->portcon, db->mls);
1976*2d543d20SAndroid Build Coastguard Worker 	cil_netifcons_to_policy(out, db->netifcon, db->mls);
1977*2d543d20SAndroid Build Coastguard Worker 	cil_ibpkeycons_to_policy(out, db->ibpkeycon, db->mls);
1978*2d543d20SAndroid Build Coastguard Worker 	cil_ibendportcons_to_policy(out, db->ibendportcon, db->mls);
1979*2d543d20SAndroid Build Coastguard Worker 	cil_nodecons_to_policy(out, db->nodecon, db->mls);
1980*2d543d20SAndroid Build Coastguard Worker 	cil_pirqcons_to_policy(out, db->pirqcon, db->mls);
1981*2d543d20SAndroid Build Coastguard Worker 	cil_iomemcons_to_policy(out, db->iomemcon, db->mls);
1982*2d543d20SAndroid Build Coastguard Worker 	cil_ioportcons_to_policy(out, db->ioportcon, db->mls);
1983*2d543d20SAndroid Build Coastguard Worker 	cil_pcidevicecons_to_policy(out, db->pcidevicecon, db->mls);
1984*2d543d20SAndroid Build Coastguard Worker 	cil_devicetreecons_to_policy(out, db->devicetreecon, db->mls);
1985*2d543d20SAndroid Build Coastguard Worker 
1986*2d543d20SAndroid Build Coastguard Worker 	for (i=0; i<CIL_LIST_NUM_LISTS; i++) {
1987*2d543d20SAndroid Build Coastguard Worker 		cil_list_destroy(&lists[i], CIL_FALSE);
1988*2d543d20SAndroid Build Coastguard Worker 	}
1989*2d543d20SAndroid Build Coastguard Worker 
1990*2d543d20SAndroid Build Coastguard Worker }
1991