xref: /aosp_15_r20/external/selinux/checkpolicy/test/dispol.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Authors: Frank Mayer <[email protected]> and Karl MacMillan <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker  *
3*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003 Tresys Technology, LLC
4*2d543d20SAndroid Build Coastguard Worker  *	This program is free software; you can redistribute it and/or modify
5*2d543d20SAndroid Build Coastguard Worker  *  	it under the terms of the GNU General Public License as published by
6*2d543d20SAndroid Build Coastguard Worker  *	the Free Software Foundation, version 2.
7*2d543d20SAndroid Build Coastguard Worker  */
8*2d543d20SAndroid Build Coastguard Worker 
9*2d543d20SAndroid Build Coastguard Worker /*
10*2d543d20SAndroid Build Coastguard Worker  * displaypol.c
11*2d543d20SAndroid Build Coastguard Worker  *
12*2d543d20SAndroid Build Coastguard Worker  * Test program to the contents of a binary policy in text
13*2d543d20SAndroid Build Coastguard Worker  * form.  This program currently only displays the
14*2d543d20SAndroid Build Coastguard Worker  * avtab (including conditional avtab) rules.
15*2d543d20SAndroid Build Coastguard Worker  *
16*2d543d20SAndroid Build Coastguard Worker  * 	displaypol binary_pol_file
17*2d543d20SAndroid Build Coastguard Worker  */
18*2d543d20SAndroid Build Coastguard Worker 
19*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
20*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/avtab.h>
21*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
22*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
23*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
24*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/polcaps.h>
25*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
26*2d543d20SAndroid Build Coastguard Worker #include <assert.h>
27*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
28*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
29*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
30*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
31*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
32*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
33*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
34*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker static const struct command {
37*2d543d20SAndroid Build Coastguard Worker 	enum {
38*2d543d20SAndroid Build Coastguard Worker 		EOL    = 0,
39*2d543d20SAndroid Build Coastguard Worker 		HEADER = 1,
40*2d543d20SAndroid Build Coastguard Worker 		CMD    = 1 << 1,
41*2d543d20SAndroid Build Coastguard Worker 		NOOPT  = 1 << 2,
42*2d543d20SAndroid Build Coastguard Worker 	} meta;
43*2d543d20SAndroid Build Coastguard Worker 	char cmd;
44*2d543d20SAndroid Build Coastguard Worker 	const char *desc;
45*2d543d20SAndroid Build Coastguard Worker } commands[] = {
46*2d543d20SAndroid Build Coastguard Worker 	{HEADER, 0, "\nSelect a command:"},
47*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '1',  "display unconditional AVTAB" },
48*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '2',  "display conditional AVTAB (entirely)"},
49*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '3',  "display conditional AVTAB (only ENABLED rules)"},
50*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '4',  "display conditional AVTAB (only DISABLED rules)"},
51*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '5',  "display booleans"},
52*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '6',  "display conditional expressions"},
53*2d543d20SAndroid Build Coastguard Worker 	{CMD|NOOPT, '7',  "change a boolean value"},
54*2d543d20SAndroid Build Coastguard Worker 	{CMD,       '8',  "display role transitions"},
55*2d543d20SAndroid Build Coastguard Worker 	{HEADER, 0, ""},
56*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'c',  "display policy capabilities"},
57*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'C',  "display classes"},
58*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'u',  "display users"},
59*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'r',  "display roles"},
60*2d543d20SAndroid Build Coastguard Worker 	{CMD,       't',  "display types"},
61*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'a',  "display type attributes"},
62*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'p',  "display the list of permissive types"},
63*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'U',  "display unknown handling setting"},
64*2d543d20SAndroid Build Coastguard Worker 	{CMD,       'F',  "display filename_trans rules"},
65*2d543d20SAndroid Build Coastguard Worker 	{HEADER, 0, ""},
66*2d543d20SAndroid Build Coastguard Worker 	{CMD|NOOPT, 'f',  "set output file"},
67*2d543d20SAndroid Build Coastguard Worker 	{CMD|NOOPT, 'm',  "display menu"},
68*2d543d20SAndroid Build Coastguard Worker 	{CMD|NOOPT, 'q',  "quit"},
69*2d543d20SAndroid Build Coastguard Worker 	{EOL,   0, "" },
70*2d543d20SAndroid Build Coastguard Worker };
71*2d543d20SAndroid Build Coastguard Worker 
usage(const char * progname)72*2d543d20SAndroid Build Coastguard Worker static __attribute__((__noreturn__)) void usage(const char *progname)
73*2d543d20SAndroid Build Coastguard Worker {
74*2d543d20SAndroid Build Coastguard Worker 	puts("Usage:");
75*2d543d20SAndroid Build Coastguard Worker 	printf(" %s [OPTIONS] binary_pol_file\n\n", progname);
76*2d543d20SAndroid Build Coastguard Worker 	puts("Options:");
77*2d543d20SAndroid Build Coastguard Worker 	puts(" -h, --help   print this help message");
78*2d543d20SAndroid Build Coastguard Worker 	puts(" -a, --actions ACTIONS   run non-interactively");
79*2d543d20SAndroid Build Coastguard Worker 	puts("");
80*2d543d20SAndroid Build Coastguard Worker 	puts("Actions:");
81*2d543d20SAndroid Build Coastguard Worker 	for (unsigned int i = 0; commands[i].meta != EOL; i++) {
82*2d543d20SAndroid Build Coastguard Worker 		if (commands[i].meta == HEADER
83*2d543d20SAndroid Build Coastguard Worker 		    || commands[i].meta & NOOPT)
84*2d543d20SAndroid Build Coastguard Worker 			continue;
85*2d543d20SAndroid Build Coastguard Worker 		printf("  %c    %s\n", commands[i].cmd, commands[i].desc);
86*2d543d20SAndroid Build Coastguard Worker 	}
87*2d543d20SAndroid Build Coastguard Worker 	puts("");
88*2d543d20SAndroid Build Coastguard Worker 	exit(1);
89*2d543d20SAndroid Build Coastguard Worker }
90*2d543d20SAndroid Build Coastguard Worker 
render_access_mask(uint32_t mask,avtab_key_t * key,policydb_t * p,FILE * fp)91*2d543d20SAndroid Build Coastguard Worker static int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
92*2d543d20SAndroid Build Coastguard Worker 		       FILE * fp)
93*2d543d20SAndroid Build Coastguard Worker {
94*2d543d20SAndroid Build Coastguard Worker 	char *perm = sepol_av_to_string(p, key->target_class, mask);
95*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "{");
96*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "%s ", perm ?: "<format-failure>");
97*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "}");
98*2d543d20SAndroid Build Coastguard Worker 	free(perm);
99*2d543d20SAndroid Build Coastguard Worker 	return 0;
100*2d543d20SAndroid Build Coastguard Worker }
101*2d543d20SAndroid Build Coastguard Worker 
render_type(uint32_t type,policydb_t * p,FILE * fp)102*2d543d20SAndroid Build Coastguard Worker static int render_type(uint32_t type, policydb_t * p, FILE * fp)
103*2d543d20SAndroid Build Coastguard Worker {
104*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
105*2d543d20SAndroid Build Coastguard Worker 	return 0;
106*2d543d20SAndroid Build Coastguard Worker }
107*2d543d20SAndroid Build Coastguard Worker 
render_key(avtab_key_t * key,policydb_t * p,FILE * fp)108*2d543d20SAndroid Build Coastguard Worker static int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
109*2d543d20SAndroid Build Coastguard Worker {
110*2d543d20SAndroid Build Coastguard Worker 	char *stype, *ttype, *tclass;
111*2d543d20SAndroid Build Coastguard Worker 	stype = p->p_type_val_to_name[key->source_type - 1];
112*2d543d20SAndroid Build Coastguard Worker 	ttype = p->p_type_val_to_name[key->target_type - 1];
113*2d543d20SAndroid Build Coastguard Worker 	tclass = p->p_class_val_to_name[key->target_class - 1];
114*2d543d20SAndroid Build Coastguard Worker 	if (stype && ttype)
115*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%s %s : %s ", stype, ttype, tclass);
116*2d543d20SAndroid Build Coastguard Worker 	else if (stype)
117*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%s %u : %s ", stype, key->target_type, tclass);
118*2d543d20SAndroid Build Coastguard Worker 	else if (ttype)
119*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%u %s : %s ", key->source_type, ttype, tclass);
120*2d543d20SAndroid Build Coastguard Worker 	else
121*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%u %u : %s ", key->source_type, key->target_type,
122*2d543d20SAndroid Build Coastguard Worker 			tclass);
123*2d543d20SAndroid Build Coastguard Worker 	return 0;
124*2d543d20SAndroid Build Coastguard Worker }
125*2d543d20SAndroid Build Coastguard Worker 
126*2d543d20SAndroid Build Coastguard Worker /* 'what' values for this function */
127*2d543d20SAndroid Build Coastguard Worker #define	RENDER_UNCONDITIONAL	0x0001	/* render all regardless of enabled state */
128*2d543d20SAndroid Build Coastguard Worker #define RENDER_ENABLED		0x0002
129*2d543d20SAndroid Build Coastguard Worker #define RENDER_DISABLED		0x0004
130*2d543d20SAndroid Build Coastguard Worker #define RENDER_CONDITIONAL	(RENDER_ENABLED|RENDER_DISABLED)
131*2d543d20SAndroid Build Coastguard Worker 
render_av_rule(avtab_key_t * key,avtab_datum_t * datum,uint32_t what,policydb_t * p,FILE * fp)132*2d543d20SAndroid Build Coastguard Worker static int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
133*2d543d20SAndroid Build Coastguard Worker 		   policydb_t * p, FILE * fp)
134*2d543d20SAndroid Build Coastguard Worker {
135*2d543d20SAndroid Build Coastguard Worker 	if (!(what & RENDER_UNCONDITIONAL)) {
136*2d543d20SAndroid Build Coastguard Worker 		if (what != RENDER_CONDITIONAL && (((what & RENDER_ENABLED)
137*2d543d20SAndroid Build Coastguard Worker 						    && !(key->
138*2d543d20SAndroid Build Coastguard Worker 							 specified &
139*2d543d20SAndroid Build Coastguard Worker 							 AVTAB_ENABLED))
140*2d543d20SAndroid Build Coastguard Worker 						   || ((what & RENDER_DISABLED)
141*2d543d20SAndroid Build Coastguard Worker 						       && (key->
142*2d543d20SAndroid Build Coastguard Worker 							   specified &
143*2d543d20SAndroid Build Coastguard Worker 							   AVTAB_ENABLED)))) {
144*2d543d20SAndroid Build Coastguard Worker 			return 0;	/* doesn't match selection criteria */
145*2d543d20SAndroid Build Coastguard Worker 		}
146*2d543d20SAndroid Build Coastguard Worker 	}
147*2d543d20SAndroid Build Coastguard Worker 
148*2d543d20SAndroid Build Coastguard Worker 	if (!(what & RENDER_UNCONDITIONAL)) {
149*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_ENABLED)
150*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "[enabled] ");
151*2d543d20SAndroid Build Coastguard Worker 		else if (!(key->specified & AVTAB_ENABLED))
152*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "[disabled] ");
153*2d543d20SAndroid Build Coastguard Worker 	}
154*2d543d20SAndroid Build Coastguard Worker 
155*2d543d20SAndroid Build Coastguard Worker 	if (key->specified & AVTAB_AV) {
156*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_ALLOWED) {
157*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "allow ");
158*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
159*2d543d20SAndroid Build Coastguard Worker 			render_access_mask(datum->data, key, p, fp);
160*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
161*2d543d20SAndroid Build Coastguard Worker 		}
162*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_AUDITALLOW) {
163*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "auditallow ");
164*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
165*2d543d20SAndroid Build Coastguard Worker 			render_access_mask(datum->data, key, p, fp);
166*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
167*2d543d20SAndroid Build Coastguard Worker 		}
168*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_AUDITDENY) {
169*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "dontaudit ");
170*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
171*2d543d20SAndroid Build Coastguard Worker 			/* We inverse the mask for dontaudit since the mask is internally stored
172*2d543d20SAndroid Build Coastguard Worker 			 * as a auditdeny mask */
173*2d543d20SAndroid Build Coastguard Worker 			render_access_mask(~datum->data, key, p, fp);
174*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
175*2d543d20SAndroid Build Coastguard Worker 		}
176*2d543d20SAndroid Build Coastguard Worker 	} else if (key->specified & AVTAB_TYPE) {
177*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_TRANSITION) {
178*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "type_transition ");
179*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
180*2d543d20SAndroid Build Coastguard Worker 			render_type(datum->data, p, fp);
181*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
182*2d543d20SAndroid Build Coastguard Worker 		}
183*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_MEMBER) {
184*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "type_member ");
185*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
186*2d543d20SAndroid Build Coastguard Worker 			render_type(datum->data, p, fp);
187*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
188*2d543d20SAndroid Build Coastguard Worker 		}
189*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_CHANGE) {
190*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "type_change ");
191*2d543d20SAndroid Build Coastguard Worker 			render_key(key, p, fp);
192*2d543d20SAndroid Build Coastguard Worker 			render_type(datum->data, p, fp);
193*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, ";\n");
194*2d543d20SAndroid Build Coastguard Worker 		}
195*2d543d20SAndroid Build Coastguard Worker 	} else if (key->specified & AVTAB_XPERMS) {
196*2d543d20SAndroid Build Coastguard Worker 		char *perms;
197*2d543d20SAndroid Build Coastguard Worker 
198*2d543d20SAndroid Build Coastguard Worker 		if (key->specified & AVTAB_XPERMS_ALLOWED)
199*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "allowxperm ");
200*2d543d20SAndroid Build Coastguard Worker 		else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
201*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "auditallowxperm ");
202*2d543d20SAndroid Build Coastguard Worker 		else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
203*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "dontauditxperm ");
204*2d543d20SAndroid Build Coastguard Worker 		render_key(key, p, fp);
205*2d543d20SAndroid Build Coastguard Worker 		perms = sepol_extended_perms_to_string(datum->xperms);
206*2d543d20SAndroid Build Coastguard Worker 		if (!perms) {
207*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "     ERROR: failed to format xperms\n");
208*2d543d20SAndroid Build Coastguard Worker 			return -1;
209*2d543d20SAndroid Build Coastguard Worker 		}
210*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%s;\n", perms);
211*2d543d20SAndroid Build Coastguard Worker 		free(perms);
212*2d543d20SAndroid Build Coastguard Worker 	} else {
213*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "     ERROR: no valid rule type specified\n");
214*2d543d20SAndroid Build Coastguard Worker 		return -1;
215*2d543d20SAndroid Build Coastguard Worker 	}
216*2d543d20SAndroid Build Coastguard Worker 	return 0;
217*2d543d20SAndroid Build Coastguard Worker }
218*2d543d20SAndroid Build Coastguard Worker 
display_avtab(avtab_t * a,uint32_t what,policydb_t * p,FILE * fp)219*2d543d20SAndroid Build Coastguard Worker static int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
220*2d543d20SAndroid Build Coastguard Worker {
221*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
222*2d543d20SAndroid Build Coastguard Worker 	avtab_ptr_t cur;
223*2d543d20SAndroid Build Coastguard Worker 
224*2d543d20SAndroid Build Coastguard Worker 	/* hmm...should have used avtab_map. */
225*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < a->nslot; i++) {
226*2d543d20SAndroid Build Coastguard Worker 		for (cur = a->htable[i]; cur; cur = cur->next) {
227*2d543d20SAndroid Build Coastguard Worker 			render_av_rule(&cur->key, &cur->datum, what, p, fp);
228*2d543d20SAndroid Build Coastguard Worker 		}
229*2d543d20SAndroid Build Coastguard Worker 	}
230*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "\n");
231*2d543d20SAndroid Build Coastguard Worker 	return 0;
232*2d543d20SAndroid Build Coastguard Worker }
233*2d543d20SAndroid Build Coastguard Worker 
display_expr(policydb_t * p,cond_expr_t * exp,FILE * fp)234*2d543d20SAndroid Build Coastguard Worker static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
235*2d543d20SAndroid Build Coastguard Worker {
236*2d543d20SAndroid Build Coastguard Worker 
237*2d543d20SAndroid Build Coastguard Worker 	cond_expr_t *cur;
238*2d543d20SAndroid Build Coastguard Worker 	for (cur = exp; cur != NULL; cur = cur->next) {
239*2d543d20SAndroid Build Coastguard Worker 		switch (cur->expr_type) {
240*2d543d20SAndroid Build Coastguard Worker 		case COND_BOOL:
241*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "%s ",
242*2d543d20SAndroid Build Coastguard Worker 				p->p_bool_val_to_name[cur->boolean - 1]);
243*2d543d20SAndroid Build Coastguard Worker 			break;
244*2d543d20SAndroid Build Coastguard Worker 		case COND_NOT:
245*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "! ");
246*2d543d20SAndroid Build Coastguard Worker 			break;
247*2d543d20SAndroid Build Coastguard Worker 		case COND_OR:
248*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "|| ");
249*2d543d20SAndroid Build Coastguard Worker 			break;
250*2d543d20SAndroid Build Coastguard Worker 		case COND_AND:
251*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "&& ");
252*2d543d20SAndroid Build Coastguard Worker 			break;
253*2d543d20SAndroid Build Coastguard Worker 		case COND_XOR:
254*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "^ ");
255*2d543d20SAndroid Build Coastguard Worker 			break;
256*2d543d20SAndroid Build Coastguard Worker 		case COND_EQ:
257*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "== ");
258*2d543d20SAndroid Build Coastguard Worker 			break;
259*2d543d20SAndroid Build Coastguard Worker 		case COND_NEQ:
260*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "!= ");
261*2d543d20SAndroid Build Coastguard Worker 			break;
262*2d543d20SAndroid Build Coastguard Worker 		default:
263*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "error!");
264*2d543d20SAndroid Build Coastguard Worker 			break;
265*2d543d20SAndroid Build Coastguard Worker 		}
266*2d543d20SAndroid Build Coastguard Worker 	}
267*2d543d20SAndroid Build Coastguard Worker }
268*2d543d20SAndroid Build Coastguard Worker 
display_cond_expressions(policydb_t * p,FILE * fp)269*2d543d20SAndroid Build Coastguard Worker static int display_cond_expressions(policydb_t * p, FILE * fp)
270*2d543d20SAndroid Build Coastguard Worker {
271*2d543d20SAndroid Build Coastguard Worker 	cond_node_t *cur;
272*2d543d20SAndroid Build Coastguard Worker 	cond_av_list_t *av_cur;
273*2d543d20SAndroid Build Coastguard Worker 
274*2d543d20SAndroid Build Coastguard Worker 	for (cur = p->cond_list; cur != NULL; cur = cur->next) {
275*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "expression: ");
276*2d543d20SAndroid Build Coastguard Worker 		display_expr(p, cur->expr, fp);
277*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "current state: %d\n", cur->cur_state);
278*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "True list:\n");
279*2d543d20SAndroid Build Coastguard Worker 		for (av_cur = cur->true_list; av_cur != NULL; av_cur = av_cur->next) {
280*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "\t");
281*2d543d20SAndroid Build Coastguard Worker 			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
282*2d543d20SAndroid Build Coastguard Worker 				       RENDER_CONDITIONAL, p, fp);
283*2d543d20SAndroid Build Coastguard Worker 		}
284*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "False list:\n");
285*2d543d20SAndroid Build Coastguard Worker 		for (av_cur = cur->false_list; av_cur != NULL; av_cur = av_cur->next) {
286*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, "\t");
287*2d543d20SAndroid Build Coastguard Worker 			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
288*2d543d20SAndroid Build Coastguard Worker 				       RENDER_CONDITIONAL, p, fp);
289*2d543d20SAndroid Build Coastguard Worker 		}
290*2d543d20SAndroid Build Coastguard Worker 	}
291*2d543d20SAndroid Build Coastguard Worker 	return 0;
292*2d543d20SAndroid Build Coastguard Worker }
293*2d543d20SAndroid Build Coastguard Worker 
display_handle_unknown(policydb_t * p,FILE * out_fp)294*2d543d20SAndroid Build Coastguard Worker static int display_handle_unknown(policydb_t * p, FILE * out_fp)
295*2d543d20SAndroid Build Coastguard Worker {
296*2d543d20SAndroid Build Coastguard Worker 	if (p->handle_unknown == ALLOW_UNKNOWN)
297*2d543d20SAndroid Build Coastguard Worker 		fprintf(out_fp, "Allow unknown classes and permissions\n");
298*2d543d20SAndroid Build Coastguard Worker 	else if (p->handle_unknown == DENY_UNKNOWN)
299*2d543d20SAndroid Build Coastguard Worker 		fprintf(out_fp, "Deny unknown classes and permissions\n");
300*2d543d20SAndroid Build Coastguard Worker 	else if (p->handle_unknown == REJECT_UNKNOWN)
301*2d543d20SAndroid Build Coastguard Worker 		fprintf(out_fp, "Reject unknown classes and permissions\n");
302*2d543d20SAndroid Build Coastguard Worker 	else
303*2d543d20SAndroid Build Coastguard Worker 		fprintf(out_fp, "<INVALID SETTING!>\n");
304*2d543d20SAndroid Build Coastguard Worker 	return 0;
305*2d543d20SAndroid Build Coastguard Worker }
306*2d543d20SAndroid Build Coastguard Worker 
change_bool(char * name,int state,policydb_t * p,FILE * fp)307*2d543d20SAndroid Build Coastguard Worker static int change_bool(char *name, int state, policydb_t * p, FILE * fp)
308*2d543d20SAndroid Build Coastguard Worker {
309*2d543d20SAndroid Build Coastguard Worker 	cond_bool_datum_t *boolean;
310*2d543d20SAndroid Build Coastguard Worker 
311*2d543d20SAndroid Build Coastguard Worker 	boolean = hashtab_search(p->p_bools.table, name);
312*2d543d20SAndroid Build Coastguard Worker 	if (boolean == NULL) {
313*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "Could not find bool %s\n", name);
314*2d543d20SAndroid Build Coastguard Worker 		return -1;
315*2d543d20SAndroid Build Coastguard Worker 	}
316*2d543d20SAndroid Build Coastguard Worker 	boolean->state = state;
317*2d543d20SAndroid Build Coastguard Worker 	evaluate_conds(p);
318*2d543d20SAndroid Build Coastguard Worker 	return 0;
319*2d543d20SAndroid Build Coastguard Worker }
320*2d543d20SAndroid Build Coastguard Worker 
display_booleans(policydb_t * p,FILE * fp)321*2d543d20SAndroid Build Coastguard Worker static int display_booleans(policydb_t * p, FILE *fp)
322*2d543d20SAndroid Build Coastguard Worker {
323*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
324*2d543d20SAndroid Build Coastguard Worker 
325*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "booleans (#%u):\n", p->p_bools.table->nel);
326*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_bools.nprim; i++) {
327*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s : %d\n", p->p_bool_val_to_name[i],
328*2d543d20SAndroid Build Coastguard Worker 			p->bool_val_to_struct[i]->state);
329*2d543d20SAndroid Build Coastguard Worker 	}
330*2d543d20SAndroid Build Coastguard Worker 	return 0;
331*2d543d20SAndroid Build Coastguard Worker }
332*2d543d20SAndroid Build Coastguard Worker 
display_policycaps(policydb_t * p,FILE * fp)333*2d543d20SAndroid Build Coastguard Worker static void display_policycaps(policydb_t * p, FILE * fp)
334*2d543d20SAndroid Build Coastguard Worker {
335*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *node;
336*2d543d20SAndroid Build Coastguard Worker 	const char *capname;
337*2d543d20SAndroid Build Coastguard Worker 	char buf[64];
338*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
339*2d543d20SAndroid Build Coastguard Worker 
340*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "policy capabilities:\n");
341*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
342*2d543d20SAndroid Build Coastguard Worker 		capname = sepol_polcap_getname(i);
343*2d543d20SAndroid Build Coastguard Worker 		if (capname == NULL) {
344*2d543d20SAndroid Build Coastguard Worker 			snprintf(buf, sizeof(buf), "unknown (%u)", i);
345*2d543d20SAndroid Build Coastguard Worker 			capname = buf;
346*2d543d20SAndroid Build Coastguard Worker 		}
347*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", capname);
348*2d543d20SAndroid Build Coastguard Worker 	}
349*2d543d20SAndroid Build Coastguard Worker }
350*2d543d20SAndroid Build Coastguard Worker 
display_classes(policydb_t * p,FILE * fp)351*2d543d20SAndroid Build Coastguard Worker static int display_classes(policydb_t * p, FILE *fp)
352*2d543d20SAndroid Build Coastguard Worker {
353*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
354*2d543d20SAndroid Build Coastguard Worker 
355*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "classes (#%u):\n", p->p_classes.table->nel);
356*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_classes.nprim; i++) {
357*2d543d20SAndroid Build Coastguard Worker 		if (!p->p_class_val_to_name[i])
358*2d543d20SAndroid Build Coastguard Worker 			continue;
359*2d543d20SAndroid Build Coastguard Worker 
360*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", p->p_class_val_to_name[i]);
361*2d543d20SAndroid Build Coastguard Worker 	}
362*2d543d20SAndroid Build Coastguard Worker 	return 0;
363*2d543d20SAndroid Build Coastguard Worker }
364*2d543d20SAndroid Build Coastguard Worker 
display_id(policydb_t * p,FILE * fp,uint32_t symbol_type,uint32_t symbol_value,const char * prefix)365*2d543d20SAndroid Build Coastguard Worker static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
366*2d543d20SAndroid Build Coastguard Worker 		       uint32_t symbol_value, const char *prefix)
367*2d543d20SAndroid Build Coastguard Worker {
368*2d543d20SAndroid Build Coastguard Worker 	const char *id = p->sym_val_to_name[symbol_type][symbol_value];
369*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, " %s%s", prefix, id);
370*2d543d20SAndroid Build Coastguard Worker }
371*2d543d20SAndroid Build Coastguard Worker 
display_permissive(policydb_t * p,FILE * fp)372*2d543d20SAndroid Build Coastguard Worker static void display_permissive(policydb_t *p, FILE *fp)
373*2d543d20SAndroid Build Coastguard Worker {
374*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *node;
375*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
376*2d543d20SAndroid Build Coastguard Worker 
377*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "permissive sids (#%u):\n", ebitmap_cardinality(&p->permissive_map));
378*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
379*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t");
380*2d543d20SAndroid Build Coastguard Worker 		display_id(p, fp, SYM_TYPES, i - 1, "");
381*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\n");
382*2d543d20SAndroid Build Coastguard Worker 	}
383*2d543d20SAndroid Build Coastguard Worker }
384*2d543d20SAndroid Build Coastguard Worker 
display_users(policydb_t * p,FILE * fp)385*2d543d20SAndroid Build Coastguard Worker static int display_users(policydb_t * p, FILE *fp)
386*2d543d20SAndroid Build Coastguard Worker {
387*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
388*2d543d20SAndroid Build Coastguard Worker 
389*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "users (#%u):\n", p->p_users.table->nel);
390*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_users.nprim; i++) {
391*2d543d20SAndroid Build Coastguard Worker 		if (!p->p_user_val_to_name[i])
392*2d543d20SAndroid Build Coastguard Worker 			continue;
393*2d543d20SAndroid Build Coastguard Worker 
394*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", p->p_user_val_to_name[i]);
395*2d543d20SAndroid Build Coastguard Worker 	}
396*2d543d20SAndroid Build Coastguard Worker 	return 0;
397*2d543d20SAndroid Build Coastguard Worker }
398*2d543d20SAndroid Build Coastguard Worker 
display_roles(policydb_t * p,FILE * fp)399*2d543d20SAndroid Build Coastguard Worker static int display_roles(policydb_t * p, FILE *fp)
400*2d543d20SAndroid Build Coastguard Worker {
401*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
402*2d543d20SAndroid Build Coastguard Worker 
403*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "roles (#%u):\n", p->p_roles.table->nel);
404*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_roles.nprim; i++) {
405*2d543d20SAndroid Build Coastguard Worker 		if (!p->p_role_val_to_name[i])
406*2d543d20SAndroid Build Coastguard Worker 			continue;
407*2d543d20SAndroid Build Coastguard Worker 
408*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", p->p_role_val_to_name[i]);
409*2d543d20SAndroid Build Coastguard Worker 	}
410*2d543d20SAndroid Build Coastguard Worker 	return 0;
411*2d543d20SAndroid Build Coastguard Worker }
412*2d543d20SAndroid Build Coastguard Worker 
display_types(policydb_t * p,FILE * fp)413*2d543d20SAndroid Build Coastguard Worker static int display_types(policydb_t * p, FILE *fp)
414*2d543d20SAndroid Build Coastguard Worker {
415*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
416*2d543d20SAndroid Build Coastguard Worker 
417*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "types (out of #%u):\n", p->p_types.table->nel);
418*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_types.nprim; i++) {
419*2d543d20SAndroid Build Coastguard Worker 		if (!p->p_type_val_to_name[i])
420*2d543d20SAndroid Build Coastguard Worker 			continue;
421*2d543d20SAndroid Build Coastguard Worker 
422*2d543d20SAndroid Build Coastguard Worker 		if (p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
423*2d543d20SAndroid Build Coastguard Worker 			continue;
424*2d543d20SAndroid Build Coastguard Worker 
425*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
426*2d543d20SAndroid Build Coastguard Worker 	}
427*2d543d20SAndroid Build Coastguard Worker 	return 0;
428*2d543d20SAndroid Build Coastguard Worker }
429*2d543d20SAndroid Build Coastguard Worker 
display_attributes(policydb_t * p,FILE * fp)430*2d543d20SAndroid Build Coastguard Worker static int display_attributes(policydb_t * p, FILE *fp)
431*2d543d20SAndroid Build Coastguard Worker {
432*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
433*2d543d20SAndroid Build Coastguard Worker 
434*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "attributes (out of #%u):\n", p->p_types.table->nel);
435*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < p->p_types.nprim; i++) {
436*2d543d20SAndroid Build Coastguard Worker 		if (!p->p_type_val_to_name[i])
437*2d543d20SAndroid Build Coastguard Worker 			continue;
438*2d543d20SAndroid Build Coastguard Worker 
439*2d543d20SAndroid Build Coastguard Worker 		if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB)
440*2d543d20SAndroid Build Coastguard Worker 			continue;
441*2d543d20SAndroid Build Coastguard Worker 
442*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
443*2d543d20SAndroid Build Coastguard Worker 	}
444*2d543d20SAndroid Build Coastguard Worker 	return 0;
445*2d543d20SAndroid Build Coastguard Worker }
446*2d543d20SAndroid Build Coastguard Worker 
display_role_trans(policydb_t * p,FILE * fp)447*2d543d20SAndroid Build Coastguard Worker static void display_role_trans(policydb_t *p, FILE *fp)
448*2d543d20SAndroid Build Coastguard Worker {
449*2d543d20SAndroid Build Coastguard Worker 	role_trans_t *rt;
450*2d543d20SAndroid Build Coastguard Worker 
451*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "role_trans rules:\n");
452*2d543d20SAndroid Build Coastguard Worker 	for (rt = p->role_tr; rt; rt = rt->next) {
453*2d543d20SAndroid Build Coastguard Worker 		display_id(p, fp, SYM_ROLES, rt->role - 1, "");
454*2d543d20SAndroid Build Coastguard Worker 		display_id(p, fp, SYM_TYPES, rt->type - 1, "");
455*2d543d20SAndroid Build Coastguard Worker 		display_id(p, fp, SYM_CLASSES, rt->tclass - 1, ":");
456*2d543d20SAndroid Build Coastguard Worker 		display_id(p, fp, SYM_ROLES, rt->new_role - 1, "");
457*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "\n");
458*2d543d20SAndroid Build Coastguard Worker 	}
459*2d543d20SAndroid Build Coastguard Worker }
460*2d543d20SAndroid Build Coastguard Worker 
461*2d543d20SAndroid Build Coastguard Worker struct filenametr_display_args {
462*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
463*2d543d20SAndroid Build Coastguard Worker 	FILE *fp;
464*2d543d20SAndroid Build Coastguard Worker };
465*2d543d20SAndroid Build Coastguard Worker 
filenametr_display(hashtab_key_t key,hashtab_datum_t datum,void * ptr)466*2d543d20SAndroid Build Coastguard Worker static int filenametr_display(hashtab_key_t key,
467*2d543d20SAndroid Build Coastguard Worker 			      hashtab_datum_t datum,
468*2d543d20SAndroid Build Coastguard Worker 			      void *ptr)
469*2d543d20SAndroid Build Coastguard Worker {
470*2d543d20SAndroid Build Coastguard Worker 	struct filename_trans_key *ft = (struct filename_trans_key *)key;
471*2d543d20SAndroid Build Coastguard Worker 	struct filename_trans_datum *ftdatum = datum;
472*2d543d20SAndroid Build Coastguard Worker 	struct filenametr_display_args *args = ptr;
473*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p = args->p;
474*2d543d20SAndroid Build Coastguard Worker 	FILE *fp = args->fp;
475*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *node;
476*2d543d20SAndroid Build Coastguard Worker 	uint32_t bit;
477*2d543d20SAndroid Build Coastguard Worker 
478*2d543d20SAndroid Build Coastguard Worker 	do {
479*2d543d20SAndroid Build Coastguard Worker 		ebitmap_for_each_positive_bit(&ftdatum->stypes, node, bit) {
480*2d543d20SAndroid Build Coastguard Worker 			display_id(p, fp, SYM_TYPES, bit, "");
481*2d543d20SAndroid Build Coastguard Worker 			display_id(p, fp, SYM_TYPES, ft->ttype - 1, "");
482*2d543d20SAndroid Build Coastguard Worker 			display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":");
483*2d543d20SAndroid Build Coastguard Worker 			display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, "");
484*2d543d20SAndroid Build Coastguard Worker 			fprintf(fp, " %s\n", ft->name);
485*2d543d20SAndroid Build Coastguard Worker 		}
486*2d543d20SAndroid Build Coastguard Worker 		ftdatum = ftdatum->next;
487*2d543d20SAndroid Build Coastguard Worker 	} while (ftdatum);
488*2d543d20SAndroid Build Coastguard Worker 
489*2d543d20SAndroid Build Coastguard Worker 	return 0;
490*2d543d20SAndroid Build Coastguard Worker }
491*2d543d20SAndroid Build Coastguard Worker 
492*2d543d20SAndroid Build Coastguard Worker 
display_filename_trans(policydb_t * p,FILE * fp)493*2d543d20SAndroid Build Coastguard Worker static void display_filename_trans(policydb_t *p, FILE *fp)
494*2d543d20SAndroid Build Coastguard Worker {
495*2d543d20SAndroid Build Coastguard Worker 	struct filenametr_display_args args;
496*2d543d20SAndroid Build Coastguard Worker 
497*2d543d20SAndroid Build Coastguard Worker 	fprintf(fp, "filename_trans rules:\n");
498*2d543d20SAndroid Build Coastguard Worker 	args.p = p;
499*2d543d20SAndroid Build Coastguard Worker 	args.fp = fp;
500*2d543d20SAndroid Build Coastguard Worker 	hashtab_map(p->filename_trans, filenametr_display, &args);
501*2d543d20SAndroid Build Coastguard Worker }
502*2d543d20SAndroid Build Coastguard Worker 
menu(void)503*2d543d20SAndroid Build Coastguard Worker static int menu(void)
504*2d543d20SAndroid Build Coastguard Worker {
505*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
506*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; commands[i].meta != EOL; i++) {
507*2d543d20SAndroid Build Coastguard Worker 		if (commands[i].meta == HEADER)
508*2d543d20SAndroid Build Coastguard Worker 			printf("%s\n", commands[i].desc);
509*2d543d20SAndroid Build Coastguard Worker 		else if (commands[i].meta & CMD)
510*2d543d20SAndroid Build Coastguard Worker 			printf("%c) %s\n", commands[i].cmd, commands[i].desc);
511*2d543d20SAndroid Build Coastguard Worker 	}
512*2d543d20SAndroid Build Coastguard Worker 	return 0;
513*2d543d20SAndroid Build Coastguard Worker }
514*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)515*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
516*2d543d20SAndroid Build Coastguard Worker {
517*2d543d20SAndroid Build Coastguard Worker 	char *ops = NULL;
518*2d543d20SAndroid Build Coastguard Worker 	char *bpol;
519*2d543d20SAndroid Build Coastguard Worker 	FILE *out_fp = stdout;
520*2d543d20SAndroid Build Coastguard Worker 	char ans[81], OutfileName[121];
521*2d543d20SAndroid Build Coastguard Worker 	int fd, ret;
522*2d543d20SAndroid Build Coastguard Worker 	struct stat sb;
523*2d543d20SAndroid Build Coastguard Worker 	void *map;
524*2d543d20SAndroid Build Coastguard Worker 	char *name;
525*2d543d20SAndroid Build Coastguard Worker 	int state;
526*2d543d20SAndroid Build Coastguard Worker 	struct policy_file pf;
527*2d543d20SAndroid Build Coastguard Worker 	policydb_t policydb;
528*2d543d20SAndroid Build Coastguard Worker 
529*2d543d20SAndroid Build Coastguard Worker 	if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
530*2d543d20SAndroid Build Coastguard Worker 		usage(argv[0]);
531*2d543d20SAndroid Build Coastguard Worker 
532*2d543d20SAndroid Build Coastguard Worker 	bpol = argv[1];
533*2d543d20SAndroid Build Coastguard Worker 	if (strcmp (bpol, "--actions") == 0 || strcmp (bpol, "-a") == 0) {
534*2d543d20SAndroid Build Coastguard Worker 		if (argc != 4) {
535*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s: unexpected number of arguments\n", argv[0]);
536*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
537*2d543d20SAndroid Build Coastguard Worker 		}
538*2d543d20SAndroid Build Coastguard Worker 		ops = argv[2];
539*2d543d20SAndroid Build Coastguard Worker 		bpol = argv[3];
540*2d543d20SAndroid Build Coastguard Worker 	} else if (bpol[0] == '-') {
541*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: unknown option: %s\n", argv[0], bpol);
542*2d543d20SAndroid Build Coastguard Worker 		usage(argv[0]);
543*2d543d20SAndroid Build Coastguard Worker 	}
544*2d543d20SAndroid Build Coastguard Worker 
545*2d543d20SAndroid Build Coastguard Worker 	fd = open(bpol, O_RDONLY);
546*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0) {
547*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't open '%s':  %s\n",
548*2d543d20SAndroid Build Coastguard Worker 			bpol, strerror(errno));
549*2d543d20SAndroid Build Coastguard Worker 		exit(1);
550*2d543d20SAndroid Build Coastguard Worker 	}
551*2d543d20SAndroid Build Coastguard Worker 	if (fstat(fd, &sb) < 0) {
552*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't stat '%s':  %s\n",
553*2d543d20SAndroid Build Coastguard Worker 			bpol, strerror(errno));
554*2d543d20SAndroid Build Coastguard Worker 		exit(1);
555*2d543d20SAndroid Build Coastguard Worker 	}
556*2d543d20SAndroid Build Coastguard Worker 	map =
557*2d543d20SAndroid Build Coastguard Worker 	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
558*2d543d20SAndroid Build Coastguard Worker 	if (map == MAP_FAILED) {
559*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't map '%s':  %s\n",
560*2d543d20SAndroid Build Coastguard Worker 			bpol, strerror(errno));
561*2d543d20SAndroid Build Coastguard Worker 		exit(1);
562*2d543d20SAndroid Build Coastguard Worker 	}
563*2d543d20SAndroid Build Coastguard Worker 
564*2d543d20SAndroid Build Coastguard Worker 	/* read the binary policy */
565*2d543d20SAndroid Build Coastguard Worker 	if (!ops)
566*2d543d20SAndroid Build Coastguard Worker 		fprintf(out_fp, "Reading policy...\n");
567*2d543d20SAndroid Build Coastguard Worker 	policy_file_init(&pf);
568*2d543d20SAndroid Build Coastguard Worker 	pf.type = PF_USE_MEMORY;
569*2d543d20SAndroid Build Coastguard Worker 	pf.data = map;
570*2d543d20SAndroid Build Coastguard Worker 	pf.len = sb.st_size;
571*2d543d20SAndroid Build Coastguard Worker 	if (policydb_init(&policydb)) {
572*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Out of memory!\n", argv[0]);
573*2d543d20SAndroid Build Coastguard Worker 		exit(1);
574*2d543d20SAndroid Build Coastguard Worker 	}
575*2d543d20SAndroid Build Coastguard Worker 	ret = policydb_read(&policydb, &pf, ops? 0: 1);
576*2d543d20SAndroid Build Coastguard Worker 	if (ret) {
577*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
578*2d543d20SAndroid Build Coastguard Worker 			"%s:  error(s) encountered while parsing configuration\n",
579*2d543d20SAndroid Build Coastguard Worker 			argv[0]);
580*2d543d20SAndroid Build Coastguard Worker 		exit(1);
581*2d543d20SAndroid Build Coastguard Worker 	}
582*2d543d20SAndroid Build Coastguard Worker 
583*2d543d20SAndroid Build Coastguard Worker 	if (!ops)
584*2d543d20SAndroid Build Coastguard Worker 		fprintf(stdout, "binary policy file loaded\n\n");
585*2d543d20SAndroid Build Coastguard Worker 	close(fd);
586*2d543d20SAndroid Build Coastguard Worker 
587*2d543d20SAndroid Build Coastguard Worker 	if (!ops)
588*2d543d20SAndroid Build Coastguard Worker 		menu();
589*2d543d20SAndroid Build Coastguard Worker 	for (;;) {
590*2d543d20SAndroid Build Coastguard Worker 		if (ops) {
591*2d543d20SAndroid Build Coastguard Worker 			puts("");
592*2d543d20SAndroid Build Coastguard Worker 			ans[0] = *ops? *ops++: 'q';
593*2d543d20SAndroid Build Coastguard Worker 			ans[1] = '\0';
594*2d543d20SAndroid Build Coastguard Worker 		} else {
595*2d543d20SAndroid Build Coastguard Worker 			printf("\nCommand (\'m\' for menu):  ");
596*2d543d20SAndroid Build Coastguard Worker 			if (fgets(ans, sizeof(ans), stdin) == NULL) {
597*2d543d20SAndroid Build Coastguard Worker 				if (feof(stdin))
598*2d543d20SAndroid Build Coastguard Worker 					break;
599*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
600*2d543d20SAndroid Build Coastguard Worker 					strerror(errno));
601*2d543d20SAndroid Build Coastguard Worker 				continue;
602*2d543d20SAndroid Build Coastguard Worker 			}
603*2d543d20SAndroid Build Coastguard Worker 		}
604*2d543d20SAndroid Build Coastguard Worker 		switch (ans[0]) {
605*2d543d20SAndroid Build Coastguard Worker 
606*2d543d20SAndroid Build Coastguard Worker 		case '1':
607*2d543d20SAndroid Build Coastguard Worker 			display_avtab(&policydb.te_avtab, RENDER_UNCONDITIONAL,
608*2d543d20SAndroid Build Coastguard Worker 				      &policydb, out_fp);
609*2d543d20SAndroid Build Coastguard Worker 			break;
610*2d543d20SAndroid Build Coastguard Worker 		case '2':
611*2d543d20SAndroid Build Coastguard Worker 			display_avtab(&policydb.te_cond_avtab,
612*2d543d20SAndroid Build Coastguard Worker 				      RENDER_CONDITIONAL, &policydb, out_fp);
613*2d543d20SAndroid Build Coastguard Worker 			break;
614*2d543d20SAndroid Build Coastguard Worker 		case '3':
615*2d543d20SAndroid Build Coastguard Worker 			display_avtab(&policydb.te_cond_avtab, RENDER_ENABLED,
616*2d543d20SAndroid Build Coastguard Worker 				      &policydb, out_fp);
617*2d543d20SAndroid Build Coastguard Worker 			break;
618*2d543d20SAndroid Build Coastguard Worker 		case '4':
619*2d543d20SAndroid Build Coastguard Worker 			display_avtab(&policydb.te_cond_avtab, RENDER_DISABLED,
620*2d543d20SAndroid Build Coastguard Worker 				      &policydb, out_fp);
621*2d543d20SAndroid Build Coastguard Worker 			break;
622*2d543d20SAndroid Build Coastguard Worker 		case '5':
623*2d543d20SAndroid Build Coastguard Worker 			display_booleans(&policydb, out_fp);
624*2d543d20SAndroid Build Coastguard Worker 			break;
625*2d543d20SAndroid Build Coastguard Worker 		case '6':
626*2d543d20SAndroid Build Coastguard Worker 			display_cond_expressions(&policydb, out_fp);
627*2d543d20SAndroid Build Coastguard Worker 			break;
628*2d543d20SAndroid Build Coastguard Worker 		case '7':
629*2d543d20SAndroid Build Coastguard Worker 			printf("name? ");
630*2d543d20SAndroid Build Coastguard Worker 			if (fgets(ans, sizeof(ans), stdin) == NULL) {
631*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
632*2d543d20SAndroid Build Coastguard Worker 						strerror(errno));
633*2d543d20SAndroid Build Coastguard Worker 				break;
634*2d543d20SAndroid Build Coastguard Worker 			}
635*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
636*2d543d20SAndroid Build Coastguard Worker 
637*2d543d20SAndroid Build Coastguard Worker 			name = strdup(ans);
638*2d543d20SAndroid Build Coastguard Worker 			if (name == NULL) {
639*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "couldn't strdup string.\n");
640*2d543d20SAndroid Build Coastguard Worker 				break;
641*2d543d20SAndroid Build Coastguard Worker 			}
642*2d543d20SAndroid Build Coastguard Worker 
643*2d543d20SAndroid Build Coastguard Worker 			printf("state? ");
644*2d543d20SAndroid Build Coastguard Worker 			if (fgets(ans, sizeof(ans), stdin) == NULL) {
645*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
646*2d543d20SAndroid Build Coastguard Worker 						strerror(errno));
647*2d543d20SAndroid Build Coastguard Worker 				break;
648*2d543d20SAndroid Build Coastguard Worker 			}
649*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
650*2d543d20SAndroid Build Coastguard Worker 
651*2d543d20SAndroid Build Coastguard Worker 			if (atoi(ans))
652*2d543d20SAndroid Build Coastguard Worker 				state = 1;
653*2d543d20SAndroid Build Coastguard Worker 			else
654*2d543d20SAndroid Build Coastguard Worker 				state = 0;
655*2d543d20SAndroid Build Coastguard Worker 
656*2d543d20SAndroid Build Coastguard Worker 			change_bool(name, state, &policydb, out_fp);
657*2d543d20SAndroid Build Coastguard Worker 			free(name);
658*2d543d20SAndroid Build Coastguard Worker 			break;
659*2d543d20SAndroid Build Coastguard Worker 		case '8':
660*2d543d20SAndroid Build Coastguard Worker 			display_role_trans(&policydb, out_fp);
661*2d543d20SAndroid Build Coastguard Worker 			break;
662*2d543d20SAndroid Build Coastguard Worker 		case 'a':
663*2d543d20SAndroid Build Coastguard Worker 			display_attributes(&policydb, out_fp);
664*2d543d20SAndroid Build Coastguard Worker 			break;
665*2d543d20SAndroid Build Coastguard Worker 		case 'c':
666*2d543d20SAndroid Build Coastguard Worker 			display_policycaps(&policydb, out_fp);
667*2d543d20SAndroid Build Coastguard Worker 			break;
668*2d543d20SAndroid Build Coastguard Worker 		case 'C':
669*2d543d20SAndroid Build Coastguard Worker 			display_classes(&policydb, out_fp);
670*2d543d20SAndroid Build Coastguard Worker 			break;
671*2d543d20SAndroid Build Coastguard Worker 		case 'p':
672*2d543d20SAndroid Build Coastguard Worker 			display_permissive(&policydb, out_fp);
673*2d543d20SAndroid Build Coastguard Worker 			break;
674*2d543d20SAndroid Build Coastguard Worker 		case 'r':
675*2d543d20SAndroid Build Coastguard Worker 			display_roles(&policydb, out_fp);
676*2d543d20SAndroid Build Coastguard Worker 			break;
677*2d543d20SAndroid Build Coastguard Worker 		case 't':
678*2d543d20SAndroid Build Coastguard Worker 			display_types(&policydb, out_fp);
679*2d543d20SAndroid Build Coastguard Worker 			break;
680*2d543d20SAndroid Build Coastguard Worker 		case 'u':
681*2d543d20SAndroid Build Coastguard Worker 			display_users(&policydb, out_fp);
682*2d543d20SAndroid Build Coastguard Worker 			break;
683*2d543d20SAndroid Build Coastguard Worker 		case 'U':
684*2d543d20SAndroid Build Coastguard Worker 			display_handle_unknown(&policydb, out_fp);
685*2d543d20SAndroid Build Coastguard Worker 			break;
686*2d543d20SAndroid Build Coastguard Worker 		case 'f':
687*2d543d20SAndroid Build Coastguard Worker 			printf
688*2d543d20SAndroid Build Coastguard Worker 			    ("\nFilename for output (<CR> for screen output): ");
689*2d543d20SAndroid Build Coastguard Worker 			if (fgets(OutfileName, sizeof(OutfileName), stdin) == NULL) {
690*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
691*2d543d20SAndroid Build Coastguard Worker 						strerror(errno));
692*2d543d20SAndroid Build Coastguard Worker 				break;
693*2d543d20SAndroid Build Coastguard Worker 			}
694*2d543d20SAndroid Build Coastguard Worker 			OutfileName[strlen(OutfileName) - 1] = '\0';	/* fix_string (remove LF) */
695*2d543d20SAndroid Build Coastguard Worker 			if (strlen(OutfileName) == 0)
696*2d543d20SAndroid Build Coastguard Worker 				out_fp = stdout;
697*2d543d20SAndroid Build Coastguard Worker 			else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
698*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Cannot open output file %s\n",
699*2d543d20SAndroid Build Coastguard Worker 					OutfileName);
700*2d543d20SAndroid Build Coastguard Worker 				out_fp = stdout;
701*2d543d20SAndroid Build Coastguard Worker 			}
702*2d543d20SAndroid Build Coastguard Worker 			if (out_fp != stdout)
703*2d543d20SAndroid Build Coastguard Worker 				printf("\nOutput to file: %s\n", OutfileName);
704*2d543d20SAndroid Build Coastguard Worker 			break;
705*2d543d20SAndroid Build Coastguard Worker 		case 'F':
706*2d543d20SAndroid Build Coastguard Worker 			display_filename_trans(&policydb, out_fp);
707*2d543d20SAndroid Build Coastguard Worker 			break;
708*2d543d20SAndroid Build Coastguard Worker 		case 'q':
709*2d543d20SAndroid Build Coastguard Worker 			policydb_destroy(&policydb);
710*2d543d20SAndroid Build Coastguard Worker 			exit(0);
711*2d543d20SAndroid Build Coastguard Worker 			break;
712*2d543d20SAndroid Build Coastguard Worker 		case 'm':
713*2d543d20SAndroid Build Coastguard Worker 			menu();
714*2d543d20SAndroid Build Coastguard Worker 			break;
715*2d543d20SAndroid Build Coastguard Worker 		default:
716*2d543d20SAndroid Build Coastguard Worker 			printf("\nInvalid choice\n");
717*2d543d20SAndroid Build Coastguard Worker 			menu();
718*2d543d20SAndroid Build Coastguard Worker 			break;
719*2d543d20SAndroid Build Coastguard Worker 
720*2d543d20SAndroid Build Coastguard Worker 		}
721*2d543d20SAndroid Build Coastguard Worker 	}
722*2d543d20SAndroid Build Coastguard Worker }
723*2d543d20SAndroid Build Coastguard Worker 
724*2d543d20SAndroid Build Coastguard Worker /* FLASK */
725