xref: /aosp_15_r20/external/selinux/checkpolicy/checkpolicy.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker 
2*2d543d20SAndroid Build Coastguard Worker /*
3*2d543d20SAndroid Build Coastguard Worker  * Author : Stephen Smalley, <[email protected]>
4*2d543d20SAndroid Build Coastguard Worker  */
5*2d543d20SAndroid Build Coastguard Worker 
6*2d543d20SAndroid Build Coastguard Worker /*
7*2d543d20SAndroid Build Coastguard Worker  * Updated: Trusted Computer Solutions, Inc. <[email protected]>
8*2d543d20SAndroid Build Coastguard Worker  *
9*2d543d20SAndroid Build Coastguard Worker  *	Support for enhanced MLS infrastructure.
10*2d543d20SAndroid Build Coastguard Worker  *
11*2d543d20SAndroid Build Coastguard Worker  * Updated: Karl MacMillan <[email protected]>
12*2d543d20SAndroid Build Coastguard Worker  *
13*2d543d20SAndroid Build Coastguard Worker  * 	Added conditional policy language extensions
14*2d543d20SAndroid Build Coastguard Worker  *
15*2d543d20SAndroid Build Coastguard Worker  * Updated: James Morris <[email protected]>
16*2d543d20SAndroid Build Coastguard Worker  *
17*2d543d20SAndroid Build Coastguard Worker  *	Added IPv6 support.
18*2d543d20SAndroid Build Coastguard Worker  *
19*2d543d20SAndroid Build Coastguard Worker  * Updated: Joshua Brindle <[email protected]>
20*2d543d20SAndroid Build Coastguard Worker  *	    Karl MacMillan <[email protected]>
21*2d543d20SAndroid Build Coastguard Worker  *          Jason Tang     <[email protected]>
22*2d543d20SAndroid Build Coastguard Worker  *
23*2d543d20SAndroid Build Coastguard Worker  *	Policy Module support.
24*2d543d20SAndroid Build Coastguard Worker  *
25*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2017 Mellanox Technologies Inc.
26*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
27*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003 - 2005 Tresys Technology, LLC
28*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003 Red Hat, Inc., James Morris <[email protected]>
29*2d543d20SAndroid Build Coastguard Worker  *	This program is free software; you can redistribute it and/or modify
30*2d543d20SAndroid Build Coastguard Worker  *  	it under the terms of the GNU General Public License as published by
31*2d543d20SAndroid Build Coastguard Worker  *	the Free Software Foundation, version 2.
32*2d543d20SAndroid Build Coastguard Worker  */
33*2d543d20SAndroid Build Coastguard Worker 
34*2d543d20SAndroid Build Coastguard Worker /* FLASK */
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker /*
37*2d543d20SAndroid Build Coastguard Worker  * checkpolicy
38*2d543d20SAndroid Build Coastguard Worker  *
39*2d543d20SAndroid Build Coastguard Worker  * Load and check a policy configuration.
40*2d543d20SAndroid Build Coastguard Worker  *
41*2d543d20SAndroid Build Coastguard Worker  * A policy configuration is created in a text format,
42*2d543d20SAndroid Build Coastguard Worker  * and then compiled into a binary format for use by
43*2d543d20SAndroid Build Coastguard Worker  * the security server.  By default, checkpolicy reads
44*2d543d20SAndroid Build Coastguard Worker  * the text format.   If '-b' is specified, then checkpolicy
45*2d543d20SAndroid Build Coastguard Worker  * reads the binary format instead.
46*2d543d20SAndroid Build Coastguard Worker  *
47*2d543d20SAndroid Build Coastguard Worker  * If '-o output_file' is specified, then checkpolicy
48*2d543d20SAndroid Build Coastguard Worker  * writes the binary format version of the configuration
49*2d543d20SAndroid Build Coastguard Worker  * to the specified output file.
50*2d543d20SAndroid Build Coastguard Worker  *
51*2d543d20SAndroid Build Coastguard Worker  * If '-d' is specified, then checkpolicy permits the user
52*2d543d20SAndroid Build Coastguard Worker  * to interactively test the security server functions with
53*2d543d20SAndroid Build Coastguard Worker  * the loaded policy configuration.
54*2d543d20SAndroid Build Coastguard Worker  *
55*2d543d20SAndroid Build Coastguard Worker  * If '-c' is specified, then the supplied parameter is used to
56*2d543d20SAndroid Build Coastguard Worker  * determine which policy version to use for generating binary
57*2d543d20SAndroid Build Coastguard Worker  * policy.  This is for compatibility with older kernels. If any
58*2d543d20SAndroid Build Coastguard Worker  * booleans or conditional rules are thrown away a warning is printed.
59*2d543d20SAndroid Build Coastguard Worker  */
60*2d543d20SAndroid Build Coastguard Worker 
61*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
62*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
63*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
64*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
65*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
66*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
67*2d543d20SAndroid Build Coastguard Worker #include <sys/socket.h>
68*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
69*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_DCCP
70*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_DCCP 33
71*2d543d20SAndroid Build Coastguard Worker #endif
72*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_SCTP
73*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_SCTP 132
74*2d543d20SAndroid Build Coastguard Worker #endif
75*2d543d20SAndroid Build Coastguard Worker #include <arpa/inet.h>
76*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
77*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
78*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
79*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
80*2d543d20SAndroid Build Coastguard Worker 
81*2d543d20SAndroid Build Coastguard Worker #include <sepol/module_to_cil.h>
82*2d543d20SAndroid Build Coastguard Worker #include <sepol/kernel_to_cil.h>
83*2d543d20SAndroid Build Coastguard Worker #include <sepol/kernel_to_conf.h>
84*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
85*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
86*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
87*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/hierarchy.h>
88*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/expand.h>
89*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/link.h>
90*2d543d20SAndroid Build Coastguard Worker 
91*2d543d20SAndroid Build Coastguard Worker #include "queue.h"
92*2d543d20SAndroid Build Coastguard Worker #include "parse_util.h"
93*2d543d20SAndroid Build Coastguard Worker 
94*2d543d20SAndroid Build Coastguard Worker // ANDROID: this code does not call policydb_destroy, perhaps others
__asan_default_options()95*2d543d20SAndroid Build Coastguard Worker const char *__asan_default_options() {
96*2d543d20SAndroid Build Coastguard Worker     return "detect_leaks=0";
97*2d543d20SAndroid Build Coastguard Worker }
98*2d543d20SAndroid Build Coastguard Worker 
99*2d543d20SAndroid Build Coastguard Worker static policydb_t policydb;
100*2d543d20SAndroid Build Coastguard Worker static sidtab_t sidtab;
101*2d543d20SAndroid Build Coastguard Worker 
102*2d543d20SAndroid Build Coastguard Worker extern policydb_t *policydbp;
103*2d543d20SAndroid Build Coastguard Worker extern int mlspol;
104*2d543d20SAndroid Build Coastguard Worker extern int werror;
105*2d543d20SAndroid Build Coastguard Worker 
106*2d543d20SAndroid Build Coastguard Worker static int handle_unknown = SEPOL_DENY_UNKNOWN;
107*2d543d20SAndroid Build Coastguard Worker static const char *txtfile = "policy.conf";
108*2d543d20SAndroid Build Coastguard Worker static const char *binfile = "policy";
109*2d543d20SAndroid Build Coastguard Worker 
usage(const char * progname)110*2d543d20SAndroid Build Coastguard Worker static __attribute__((__noreturn__)) void usage(const char *progname)
111*2d543d20SAndroid Build Coastguard Worker {
112*2d543d20SAndroid Build Coastguard Worker 	printf
113*2d543d20SAndroid Build Coastguard Worker 	    ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
114*2d543d20SAndroid Build Coastguard Worker 	     "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
115*2d543d20SAndroid Build Coastguard Worker 	     "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
116*2d543d20SAndroid Build Coastguard Worker 	     progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
117*2d543d20SAndroid Build Coastguard Worker 	exit(1);
118*2d543d20SAndroid Build Coastguard Worker }
119*2d543d20SAndroid Build Coastguard Worker 
120*2d543d20SAndroid Build Coastguard Worker #define FGETS(out, size, in) \
121*2d543d20SAndroid Build Coastguard Worker do { \
122*2d543d20SAndroid Build Coastguard Worker 	if (fgets(out,size,in)==NULL) {	\
123*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, \
124*2d543d20SAndroid Build Coastguard Worker 			strerror(errno)); \
125*2d543d20SAndroid Build Coastguard Worker 		exit(1);\
126*2d543d20SAndroid Build Coastguard Worker 	} \
127*2d543d20SAndroid Build Coastguard Worker } while (0)
128*2d543d20SAndroid Build Coastguard Worker 
print_sid(sepol_security_id_t sid,context_struct_t * context,void * data)129*2d543d20SAndroid Build Coastguard Worker static int print_sid(sepol_security_id_t sid,
130*2d543d20SAndroid Build Coastguard Worker 		     context_struct_t * context
131*2d543d20SAndroid Build Coastguard Worker 		     __attribute__ ((unused)), void *data
132*2d543d20SAndroid Build Coastguard Worker 		     __attribute__ ((unused)))
133*2d543d20SAndroid Build Coastguard Worker {
134*2d543d20SAndroid Build Coastguard Worker 	sepol_security_context_t scontext;
135*2d543d20SAndroid Build Coastguard Worker 	size_t scontext_len;
136*2d543d20SAndroid Build Coastguard Worker 	int rc;
137*2d543d20SAndroid Build Coastguard Worker 
138*2d543d20SAndroid Build Coastguard Worker 	rc = sepol_sid_to_context(sid, &scontext, &scontext_len);
139*2d543d20SAndroid Build Coastguard Worker 	if (rc)
140*2d543d20SAndroid Build Coastguard Worker 		printf("sid %d -> error %d\n", sid, rc);
141*2d543d20SAndroid Build Coastguard Worker 	else {
142*2d543d20SAndroid Build Coastguard Worker 		printf("sid %d -> scontext %s\n", sid, scontext);
143*2d543d20SAndroid Build Coastguard Worker 		free(scontext);
144*2d543d20SAndroid Build Coastguard Worker 	}
145*2d543d20SAndroid Build Coastguard Worker 	return 0;
146*2d543d20SAndroid Build Coastguard Worker }
147*2d543d20SAndroid Build Coastguard Worker 
148*2d543d20SAndroid Build Coastguard Worker struct val_to_name {
149*2d543d20SAndroid Build Coastguard Worker 	unsigned int val;
150*2d543d20SAndroid Build Coastguard Worker 	char *name;
151*2d543d20SAndroid Build Coastguard Worker };
152*2d543d20SAndroid Build Coastguard Worker 
find_perm(hashtab_key_t key,hashtab_datum_t datum,void * p)153*2d543d20SAndroid Build Coastguard Worker static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
154*2d543d20SAndroid Build Coastguard Worker {
155*2d543d20SAndroid Build Coastguard Worker 	struct val_to_name *v = p;
156*2d543d20SAndroid Build Coastguard Worker 	perm_datum_t *perdatum;
157*2d543d20SAndroid Build Coastguard Worker 
158*2d543d20SAndroid Build Coastguard Worker 	perdatum = (perm_datum_t *) datum;
159*2d543d20SAndroid Build Coastguard Worker 
160*2d543d20SAndroid Build Coastguard Worker 	if (v->val == perdatum->s.value) {
161*2d543d20SAndroid Build Coastguard Worker 		v->name = key;
162*2d543d20SAndroid Build Coastguard Worker 		return 1;
163*2d543d20SAndroid Build Coastguard Worker 	}
164*2d543d20SAndroid Build Coastguard Worker 
165*2d543d20SAndroid Build Coastguard Worker 	return 0;
166*2d543d20SAndroid Build Coastguard Worker }
167*2d543d20SAndroid Build Coastguard Worker 
168*2d543d20SAndroid Build Coastguard Worker #ifdef EQUIVTYPES
insert_type_rule(avtab_key_t * k,avtab_datum_t * d,struct avtab_node * type_rules)169*2d543d20SAndroid Build Coastguard Worker static int insert_type_rule(avtab_key_t * k, avtab_datum_t * d,
170*2d543d20SAndroid Build Coastguard Worker 			    struct avtab_node *type_rules)
171*2d543d20SAndroid Build Coastguard Worker {
172*2d543d20SAndroid Build Coastguard Worker 	struct avtab_node *p, *c, *n;
173*2d543d20SAndroid Build Coastguard Worker 
174*2d543d20SAndroid Build Coastguard Worker 	for (p = type_rules, c = type_rules->next; c; p = c, c = c->next) {
175*2d543d20SAndroid Build Coastguard Worker 		/*
176*2d543d20SAndroid Build Coastguard Worker 		 * Find the insertion point, keeping the list
177*2d543d20SAndroid Build Coastguard Worker 		 * ordered by source type, then target type, then
178*2d543d20SAndroid Build Coastguard Worker 		 * target class.
179*2d543d20SAndroid Build Coastguard Worker 		 */
180*2d543d20SAndroid Build Coastguard Worker 		if (k->source_type < c->key.source_type)
181*2d543d20SAndroid Build Coastguard Worker 			break;
182*2d543d20SAndroid Build Coastguard Worker 		if (k->source_type == c->key.source_type &&
183*2d543d20SAndroid Build Coastguard Worker 		    k->target_type < c->key.target_type)
184*2d543d20SAndroid Build Coastguard Worker 			break;
185*2d543d20SAndroid Build Coastguard Worker 		if (k->source_type == c->key.source_type &&
186*2d543d20SAndroid Build Coastguard Worker 		    k->target_type == c->key.target_type &&
187*2d543d20SAndroid Build Coastguard Worker 		    k->target_class < c->key.target_class)
188*2d543d20SAndroid Build Coastguard Worker 			break;
189*2d543d20SAndroid Build Coastguard Worker 	}
190*2d543d20SAndroid Build Coastguard Worker 
191*2d543d20SAndroid Build Coastguard Worker 	/* Insert the rule */
192*2d543d20SAndroid Build Coastguard Worker 	n = malloc(sizeof(struct avtab_node));
193*2d543d20SAndroid Build Coastguard Worker 	if (!n) {
194*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "out of memory\n");
195*2d543d20SAndroid Build Coastguard Worker 		exit(1);
196*2d543d20SAndroid Build Coastguard Worker 	}
197*2d543d20SAndroid Build Coastguard Worker 
198*2d543d20SAndroid Build Coastguard Worker 	n->key = *k;
199*2d543d20SAndroid Build Coastguard Worker 	n->datum = *d;
200*2d543d20SAndroid Build Coastguard Worker 	n->next = p->next;
201*2d543d20SAndroid Build Coastguard Worker 	p->next = n;
202*2d543d20SAndroid Build Coastguard Worker 	return 0;
203*2d543d20SAndroid Build Coastguard Worker }
204*2d543d20SAndroid Build Coastguard Worker 
create_type_rules(avtab_key_t * k,avtab_datum_t * d,void * args)205*2d543d20SAndroid Build Coastguard Worker static int create_type_rules(avtab_key_t * k, avtab_datum_t * d, void *args)
206*2d543d20SAndroid Build Coastguard Worker {
207*2d543d20SAndroid Build Coastguard Worker 	struct avtab_node *type_rules = args;
208*2d543d20SAndroid Build Coastguard Worker 
209*2d543d20SAndroid Build Coastguard Worker 	if (d->specified & AVTAB_ALLOWED) {
210*2d543d20SAndroid Build Coastguard Worker 		/*
211*2d543d20SAndroid Build Coastguard Worker 		 * Insert the rule into the lists for both
212*2d543d20SAndroid Build Coastguard Worker 		 * the source type and the target type.
213*2d543d20SAndroid Build Coastguard Worker 		 */
214*2d543d20SAndroid Build Coastguard Worker 		if (insert_type_rule(k, d, &type_rules[k->source_type - 1]))
215*2d543d20SAndroid Build Coastguard Worker 			return -1;
216*2d543d20SAndroid Build Coastguard Worker 		if (insert_type_rule(k, d, &type_rules[k->target_type - 1]))
217*2d543d20SAndroid Build Coastguard Worker 			return -1;
218*2d543d20SAndroid Build Coastguard Worker 	}
219*2d543d20SAndroid Build Coastguard Worker 
220*2d543d20SAndroid Build Coastguard Worker 	return 0;
221*2d543d20SAndroid Build Coastguard Worker }
222*2d543d20SAndroid Build Coastguard Worker 
free_type_rules(struct avtab_node * l)223*2d543d20SAndroid Build Coastguard Worker static void free_type_rules(struct avtab_node *l)
224*2d543d20SAndroid Build Coastguard Worker {
225*2d543d20SAndroid Build Coastguard Worker 	struct avtab_node *tmp;
226*2d543d20SAndroid Build Coastguard Worker 
227*2d543d20SAndroid Build Coastguard Worker 	while (l) {
228*2d543d20SAndroid Build Coastguard Worker 		tmp = l;
229*2d543d20SAndroid Build Coastguard Worker 		l = l->next;
230*2d543d20SAndroid Build Coastguard Worker 		free(tmp);
231*2d543d20SAndroid Build Coastguard Worker 	}
232*2d543d20SAndroid Build Coastguard Worker }
233*2d543d20SAndroid Build Coastguard Worker 
identify_equiv_types(void)234*2d543d20SAndroid Build Coastguard Worker static int identify_equiv_types(void)
235*2d543d20SAndroid Build Coastguard Worker {
236*2d543d20SAndroid Build Coastguard Worker 	struct avtab_node *type_rules, *l1, *l2;
237*2d543d20SAndroid Build Coastguard Worker 	int i, j;
238*2d543d20SAndroid Build Coastguard Worker 
239*2d543d20SAndroid Build Coastguard Worker 	/*
240*2d543d20SAndroid Build Coastguard Worker 	 * Create a list of access vector rules for each type
241*2d543d20SAndroid Build Coastguard Worker 	 * from the access vector table.
242*2d543d20SAndroid Build Coastguard Worker 	 */
243*2d543d20SAndroid Build Coastguard Worker 	type_rules = malloc(sizeof(struct avtab_node) * policydb.p_types.nprim);
244*2d543d20SAndroid Build Coastguard Worker 	if (!type_rules) {
245*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "out of memory\n");
246*2d543d20SAndroid Build Coastguard Worker 		exit(1);
247*2d543d20SAndroid Build Coastguard Worker 	}
248*2d543d20SAndroid Build Coastguard Worker 	memset(type_rules, 0,
249*2d543d20SAndroid Build Coastguard Worker 	       sizeof(struct avtab_node) * policydb.p_types.nprim);
250*2d543d20SAndroid Build Coastguard Worker 	if (avtab_map(&policydb.te_avtab, create_type_rules, type_rules))
251*2d543d20SAndroid Build Coastguard Worker 		exit(1);
252*2d543d20SAndroid Build Coastguard Worker 
253*2d543d20SAndroid Build Coastguard Worker 	/*
254*2d543d20SAndroid Build Coastguard Worker 	 * Compare the type lists and identify equivalent types.
255*2d543d20SAndroid Build Coastguard Worker 	 */
256*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < policydb.p_types.nprim - 1; i++) {
257*2d543d20SAndroid Build Coastguard Worker 		if (!type_rules[i].next)
258*2d543d20SAndroid Build Coastguard Worker 			continue;
259*2d543d20SAndroid Build Coastguard Worker 		for (j = i + 1; j < policydb.p_types.nprim; j++) {
260*2d543d20SAndroid Build Coastguard Worker 			for (l1 = type_rules[i].next, l2 = type_rules[j].next;
261*2d543d20SAndroid Build Coastguard Worker 			     l1 && l2; l1 = l1->next, l2 = l2->next) {
262*2d543d20SAndroid Build Coastguard Worker 				if (l2->key.source_type == (j + 1)) {
263*2d543d20SAndroid Build Coastguard Worker 					if (l1->key.source_type != (i + 1))
264*2d543d20SAndroid Build Coastguard Worker 						break;
265*2d543d20SAndroid Build Coastguard Worker 				} else {
266*2d543d20SAndroid Build Coastguard Worker 					if (l1->key.source_type !=
267*2d543d20SAndroid Build Coastguard Worker 					    l2->key.source_type)
268*2d543d20SAndroid Build Coastguard Worker 						break;
269*2d543d20SAndroid Build Coastguard Worker 				}
270*2d543d20SAndroid Build Coastguard Worker 				if (l2->key.target_type == (j + 1)) {
271*2d543d20SAndroid Build Coastguard Worker 					if (l1->key.target_type != (i + 1))
272*2d543d20SAndroid Build Coastguard Worker 						break;
273*2d543d20SAndroid Build Coastguard Worker 				} else {
274*2d543d20SAndroid Build Coastguard Worker 					if (l1->key.target_type !=
275*2d543d20SAndroid Build Coastguard Worker 					    l2->key.target_type)
276*2d543d20SAndroid Build Coastguard Worker 						break;
277*2d543d20SAndroid Build Coastguard Worker 				}
278*2d543d20SAndroid Build Coastguard Worker 				if (l1->key.target_class != l2->key.target_class
279*2d543d20SAndroid Build Coastguard Worker 				    || l1->datum.allowed != l2->datum.allowed)
280*2d543d20SAndroid Build Coastguard Worker 					break;
281*2d543d20SAndroid Build Coastguard Worker 			}
282*2d543d20SAndroid Build Coastguard Worker 			if (l1 || l2)
283*2d543d20SAndroid Build Coastguard Worker 				continue;
284*2d543d20SAndroid Build Coastguard Worker 			free_type_rules(type_rules[j].next);
285*2d543d20SAndroid Build Coastguard Worker 			type_rules[j].next = NULL;
286*2d543d20SAndroid Build Coastguard Worker 			printf("Types %s and %s are equivalent.\n",
287*2d543d20SAndroid Build Coastguard Worker 			       policydb.p_type_val_to_name[i],
288*2d543d20SAndroid Build Coastguard Worker 			       policydb.p_type_val_to_name[j]);
289*2d543d20SAndroid Build Coastguard Worker 		}
290*2d543d20SAndroid Build Coastguard Worker 		free_type_rules(type_rules[i].next);
291*2d543d20SAndroid Build Coastguard Worker 		type_rules[i].next = NULL;
292*2d543d20SAndroid Build Coastguard Worker 	}
293*2d543d20SAndroid Build Coastguard Worker 
294*2d543d20SAndroid Build Coastguard Worker 	free(type_rules);
295*2d543d20SAndroid Build Coastguard Worker 	return 0;
296*2d543d20SAndroid Build Coastguard Worker }
297*2d543d20SAndroid Build Coastguard Worker #endif
298*2d543d20SAndroid Build Coastguard Worker 
display_bools(void)299*2d543d20SAndroid Build Coastguard Worker static int display_bools(void)
300*2d543d20SAndroid Build Coastguard Worker {
301*2d543d20SAndroid Build Coastguard Worker 	uint32_t i;
302*2d543d20SAndroid Build Coastguard Worker 
303*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < policydbp->p_bools.nprim; i++) {
304*2d543d20SAndroid Build Coastguard Worker 		printf("%s : %d\n", policydbp->p_bool_val_to_name[i],
305*2d543d20SAndroid Build Coastguard Worker 		       policydbp->bool_val_to_struct[i]->state);
306*2d543d20SAndroid Build Coastguard Worker 	}
307*2d543d20SAndroid Build Coastguard Worker 	return 0;
308*2d543d20SAndroid Build Coastguard Worker }
309*2d543d20SAndroid Build Coastguard Worker 
display_expr(const cond_expr_t * exp)310*2d543d20SAndroid Build Coastguard Worker static void display_expr(const cond_expr_t * exp)
311*2d543d20SAndroid Build Coastguard Worker {
312*2d543d20SAndroid Build Coastguard Worker 
313*2d543d20SAndroid Build Coastguard Worker 	const cond_expr_t *cur;
314*2d543d20SAndroid Build Coastguard Worker 	for (cur = exp; cur != NULL; cur = cur->next) {
315*2d543d20SAndroid Build Coastguard Worker 		switch (cur->expr_type) {
316*2d543d20SAndroid Build Coastguard Worker 		case COND_BOOL:
317*2d543d20SAndroid Build Coastguard Worker 			printf("%s ",
318*2d543d20SAndroid Build Coastguard Worker 			       policydbp->p_bool_val_to_name[cur->boolean - 1]);
319*2d543d20SAndroid Build Coastguard Worker 			break;
320*2d543d20SAndroid Build Coastguard Worker 		case COND_NOT:
321*2d543d20SAndroid Build Coastguard Worker 			printf("! ");
322*2d543d20SAndroid Build Coastguard Worker 			break;
323*2d543d20SAndroid Build Coastguard Worker 		case COND_OR:
324*2d543d20SAndroid Build Coastguard Worker 			printf("|| ");
325*2d543d20SAndroid Build Coastguard Worker 			break;
326*2d543d20SAndroid Build Coastguard Worker 		case COND_AND:
327*2d543d20SAndroid Build Coastguard Worker 			printf("&& ");
328*2d543d20SAndroid Build Coastguard Worker 			break;
329*2d543d20SAndroid Build Coastguard Worker 		case COND_XOR:
330*2d543d20SAndroid Build Coastguard Worker 			printf("^ ");
331*2d543d20SAndroid Build Coastguard Worker 			break;
332*2d543d20SAndroid Build Coastguard Worker 		case COND_EQ:
333*2d543d20SAndroid Build Coastguard Worker 			printf("== ");
334*2d543d20SAndroid Build Coastguard Worker 			break;
335*2d543d20SAndroid Build Coastguard Worker 		case COND_NEQ:
336*2d543d20SAndroid Build Coastguard Worker 			printf("!= ");
337*2d543d20SAndroid Build Coastguard Worker 			break;
338*2d543d20SAndroid Build Coastguard Worker 		default:
339*2d543d20SAndroid Build Coastguard Worker 			printf("error!");
340*2d543d20SAndroid Build Coastguard Worker 			break;
341*2d543d20SAndroid Build Coastguard Worker 		}
342*2d543d20SAndroid Build Coastguard Worker 	}
343*2d543d20SAndroid Build Coastguard Worker }
344*2d543d20SAndroid Build Coastguard Worker 
display_cond_expressions(void)345*2d543d20SAndroid Build Coastguard Worker static int display_cond_expressions(void)
346*2d543d20SAndroid Build Coastguard Worker {
347*2d543d20SAndroid Build Coastguard Worker 	const cond_node_t *cur;
348*2d543d20SAndroid Build Coastguard Worker 
349*2d543d20SAndroid Build Coastguard Worker 	for (cur = policydbp->cond_list; cur != NULL; cur = cur->next) {
350*2d543d20SAndroid Build Coastguard Worker 		printf("expression: ");
351*2d543d20SAndroid Build Coastguard Worker 		display_expr(cur->expr);
352*2d543d20SAndroid Build Coastguard Worker 		printf("current state: %d\n", cur->cur_state);
353*2d543d20SAndroid Build Coastguard Worker 	}
354*2d543d20SAndroid Build Coastguard Worker 	return 0;
355*2d543d20SAndroid Build Coastguard Worker }
356*2d543d20SAndroid Build Coastguard Worker 
change_bool(const char * name,int state)357*2d543d20SAndroid Build Coastguard Worker static int change_bool(const char *name, int state)
358*2d543d20SAndroid Build Coastguard Worker {
359*2d543d20SAndroid Build Coastguard Worker 	cond_bool_datum_t *boolean;
360*2d543d20SAndroid Build Coastguard Worker 
361*2d543d20SAndroid Build Coastguard Worker 	boolean = hashtab_search(policydbp->p_bools.table, name);
362*2d543d20SAndroid Build Coastguard Worker 	if (boolean == NULL) {
363*2d543d20SAndroid Build Coastguard Worker 		printf("Could not find bool %s\n", name);
364*2d543d20SAndroid Build Coastguard Worker 		return -1;
365*2d543d20SAndroid Build Coastguard Worker 	}
366*2d543d20SAndroid Build Coastguard Worker 	boolean->state = state;
367*2d543d20SAndroid Build Coastguard Worker 	evaluate_conds(policydbp);
368*2d543d20SAndroid Build Coastguard Worker 	return 0;
369*2d543d20SAndroid Build Coastguard Worker }
370*2d543d20SAndroid Build Coastguard Worker 
check_level(hashtab_key_t key,hashtab_datum_t datum,void * arg)371*2d543d20SAndroid Build Coastguard Worker static int check_level(hashtab_key_t key, hashtab_datum_t datum, void *arg __attribute__ ((unused)))
372*2d543d20SAndroid Build Coastguard Worker {
373*2d543d20SAndroid Build Coastguard Worker 	level_datum_t *levdatum = (level_datum_t *) datum;
374*2d543d20SAndroid Build Coastguard Worker 
375*2d543d20SAndroid Build Coastguard Worker 	if (!levdatum->isalias && levdatum->notdefined) {
376*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Error:  sensitivity %s was not used in a level definition!\n",
377*2d543d20SAndroid Build Coastguard Worker 				key);
378*2d543d20SAndroid Build Coastguard Worker 		return -1;
379*2d543d20SAndroid Build Coastguard Worker 	}
380*2d543d20SAndroid Build Coastguard Worker 	return 0;
381*2d543d20SAndroid Build Coastguard Worker }
382*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)383*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
384*2d543d20SAndroid Build Coastguard Worker {
385*2d543d20SAndroid Build Coastguard Worker 	policydb_t parse_policy;
386*2d543d20SAndroid Build Coastguard Worker 	sepol_security_class_t tclass;
387*2d543d20SAndroid Build Coastguard Worker 	sepol_security_id_t ssid, tsid, *sids, oldsid, newsid, tasksid;
388*2d543d20SAndroid Build Coastguard Worker 	sepol_security_context_t scontext;
389*2d543d20SAndroid Build Coastguard Worker 	struct sepol_av_decision avd;
390*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *cladatum;
391*2d543d20SAndroid Build Coastguard Worker 	const char *file = txtfile;
392*2d543d20SAndroid Build Coastguard Worker 	char ans[80 + 1], *path, *fstype;
393*2d543d20SAndroid Build Coastguard Worker 	const char *outfile = NULL;
394*2d543d20SAndroid Build Coastguard Worker 	size_t scontext_len, pathlen;
395*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
396*2d543d20SAndroid Build Coastguard Worker 	unsigned int protocol, port;
397*2d543d20SAndroid Build Coastguard Worker 	unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, disable_neverallow = 0;
398*2d543d20SAndroid Build Coastguard Worker 	struct val_to_name v;
399*2d543d20SAndroid Build Coastguard Worker 	int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
400*2d543d20SAndroid Build Coastguard Worker 	unsigned int policyvers = 0;
401*2d543d20SAndroid Build Coastguard Worker 	unsigned int nel, uret;
402*2d543d20SAndroid Build Coastguard Worker 	struct stat sb;
403*2d543d20SAndroid Build Coastguard Worker 	void *map;
404*2d543d20SAndroid Build Coastguard Worker 	FILE *outfp = NULL;
405*2d543d20SAndroid Build Coastguard Worker 	char *name;
406*2d543d20SAndroid Build Coastguard Worker 	int state;
407*2d543d20SAndroid Build Coastguard Worker 	int show_version = 0;
408*2d543d20SAndroid Build Coastguard Worker 	char *reason_buf = NULL;
409*2d543d20SAndroid Build Coastguard Worker 	unsigned int reason;
410*2d543d20SAndroid Build Coastguard Worker 	int flags;
411*2d543d20SAndroid Build Coastguard Worker 	struct policy_file pf;
412*2d543d20SAndroid Build Coastguard Worker 	const struct option long_options[] = {
413*2d543d20SAndroid Build Coastguard Worker 		{"output", required_argument, NULL, 'o'},
414*2d543d20SAndroid Build Coastguard Worker 		{"target", required_argument, NULL, 't'},
415*2d543d20SAndroid Build Coastguard Worker 		{"binary", no_argument, NULL, 'b'},
416*2d543d20SAndroid Build Coastguard Worker 		{"debug", no_argument, NULL, 'd'},
417*2d543d20SAndroid Build Coastguard Worker 		{"version", no_argument, NULL, 'V'},
418*2d543d20SAndroid Build Coastguard Worker 		{"handle-unknown", required_argument, NULL, 'U'},
419*2d543d20SAndroid Build Coastguard Worker 		{"mls", no_argument, NULL, 'M'},
420*2d543d20SAndroid Build Coastguard Worker 		{"disable-neverallow", no_argument, NULL, 'N'},
421*2d543d20SAndroid Build Coastguard Worker 		{"cil", no_argument, NULL, 'C'},
422*2d543d20SAndroid Build Coastguard Worker 		{"conf",no_argument, NULL, 'F'},
423*2d543d20SAndroid Build Coastguard Worker 		{"sort", no_argument, NULL, 'S'},
424*2d543d20SAndroid Build Coastguard Worker 		{"optimize", no_argument, NULL, 'O'},
425*2d543d20SAndroid Build Coastguard Worker 		{"werror", no_argument, NULL, 'E'},
426*2d543d20SAndroid Build Coastguard Worker 		{"help", no_argument, NULL, 'h'},
427*2d543d20SAndroid Build Coastguard Worker 		{NULL, 0, NULL, 0}
428*2d543d20SAndroid Build Coastguard Worker 	};
429*2d543d20SAndroid Build Coastguard Worker 
430*2d543d20SAndroid Build Coastguard Worker 	while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
431*2d543d20SAndroid Build Coastguard Worker 		switch (ch) {
432*2d543d20SAndroid Build Coastguard Worker 		case 'o':
433*2d543d20SAndroid Build Coastguard Worker 			outfile = optarg;
434*2d543d20SAndroid Build Coastguard Worker 			break;
435*2d543d20SAndroid Build Coastguard Worker 		case 't':
436*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "Xen"))
437*2d543d20SAndroid Build Coastguard Worker 				target = SEPOL_TARGET_XEN;
438*2d543d20SAndroid Build Coastguard Worker 			else if (!strcasecmp(optarg, "SELinux"))
439*2d543d20SAndroid Build Coastguard Worker 				target = SEPOL_TARGET_SELINUX;
440*2d543d20SAndroid Build Coastguard Worker 			else{
441*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  Unknown target platform:"
442*2d543d20SAndroid Build Coastguard Worker 					"%s\n", argv[0], optarg);
443*2d543d20SAndroid Build Coastguard Worker 				exit(1);
444*2d543d20SAndroid Build Coastguard Worker 			}
445*2d543d20SAndroid Build Coastguard Worker 			break;
446*2d543d20SAndroid Build Coastguard Worker 		case 'b':
447*2d543d20SAndroid Build Coastguard Worker 			binary = 1;
448*2d543d20SAndroid Build Coastguard Worker 			file = binfile;
449*2d543d20SAndroid Build Coastguard Worker 			break;
450*2d543d20SAndroid Build Coastguard Worker 		case 'd':
451*2d543d20SAndroid Build Coastguard Worker 			debug = 1;
452*2d543d20SAndroid Build Coastguard Worker 			break;
453*2d543d20SAndroid Build Coastguard Worker 		case 'V':
454*2d543d20SAndroid Build Coastguard Worker 			show_version = 1;
455*2d543d20SAndroid Build Coastguard Worker 			break;
456*2d543d20SAndroid Build Coastguard Worker 		case 'U':
457*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "deny")) {
458*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = DENY_UNKNOWN;
459*2d543d20SAndroid Build Coastguard Worker 				break;
460*2d543d20SAndroid Build Coastguard Worker 			}
461*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "allow")) {
462*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = ALLOW_UNKNOWN;
463*2d543d20SAndroid Build Coastguard Worker 				break;
464*2d543d20SAndroid Build Coastguard Worker 			}
465*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "reject")) {
466*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = REJECT_UNKNOWN;
467*2d543d20SAndroid Build Coastguard Worker 				break;
468*2d543d20SAndroid Build Coastguard Worker 			}
469*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
470*2d543d20SAndroid Build Coastguard Worker 		case 'S':
471*2d543d20SAndroid Build Coastguard Worker 			sort = 1;
472*2d543d20SAndroid Build Coastguard Worker 			break;
473*2d543d20SAndroid Build Coastguard Worker 		case 'O':
474*2d543d20SAndroid Build Coastguard Worker 			optimize = 1;
475*2d543d20SAndroid Build Coastguard Worker 			break;
476*2d543d20SAndroid Build Coastguard Worker 		case 'M':
477*2d543d20SAndroid Build Coastguard Worker 			mlspol = 1;
478*2d543d20SAndroid Build Coastguard Worker 			break;
479*2d543d20SAndroid Build Coastguard Worker 		case 'N':
480*2d543d20SAndroid Build Coastguard Worker 			disable_neverallow = 1;
481*2d543d20SAndroid Build Coastguard Worker 			break;
482*2d543d20SAndroid Build Coastguard Worker 		case 'C':
483*2d543d20SAndroid Build Coastguard Worker 			cil = 1;
484*2d543d20SAndroid Build Coastguard Worker 			break;
485*2d543d20SAndroid Build Coastguard Worker 		case 'F':
486*2d543d20SAndroid Build Coastguard Worker 			conf = 1;
487*2d543d20SAndroid Build Coastguard Worker 			break;
488*2d543d20SAndroid Build Coastguard Worker 		case 'c':{
489*2d543d20SAndroid Build Coastguard Worker 				long int n;
490*2d543d20SAndroid Build Coastguard Worker 				errno = 0;
491*2d543d20SAndroid Build Coastguard Worker 				n = strtol(optarg, NULL, 10);
492*2d543d20SAndroid Build Coastguard Worker 				if (errno) {
493*2d543d20SAndroid Build Coastguard Worker 					fprintf(stderr,
494*2d543d20SAndroid Build Coastguard Worker 						"Invalid policyvers specified: %s\n",
495*2d543d20SAndroid Build Coastguard Worker 						optarg);
496*2d543d20SAndroid Build Coastguard Worker 					usage(argv[0]);
497*2d543d20SAndroid Build Coastguard Worker 					exit(1);
498*2d543d20SAndroid Build Coastguard Worker 				}
499*2d543d20SAndroid Build Coastguard Worker 				if (n < POLICYDB_VERSION_MIN
500*2d543d20SAndroid Build Coastguard Worker 				    || n > POLICYDB_VERSION_MAX) {
501*2d543d20SAndroid Build Coastguard Worker 					fprintf(stderr,
502*2d543d20SAndroid Build Coastguard Worker 						"policyvers value %ld not in range %d-%d\n",
503*2d543d20SAndroid Build Coastguard Worker 						n, POLICYDB_VERSION_MIN,
504*2d543d20SAndroid Build Coastguard Worker 						POLICYDB_VERSION_MAX);
505*2d543d20SAndroid Build Coastguard Worker 					usage(argv[0]);
506*2d543d20SAndroid Build Coastguard Worker 					exit(1);
507*2d543d20SAndroid Build Coastguard Worker 				}
508*2d543d20SAndroid Build Coastguard Worker 				policyvers = n;
509*2d543d20SAndroid Build Coastguard Worker 				break;
510*2d543d20SAndroid Build Coastguard Worker 			}
511*2d543d20SAndroid Build Coastguard Worker 		case 'E':
512*2d543d20SAndroid Build Coastguard Worker 			 werror = 1;
513*2d543d20SAndroid Build Coastguard Worker 			 break;
514*2d543d20SAndroid Build Coastguard Worker 		case 'h':
515*2d543d20SAndroid Build Coastguard Worker 		default:
516*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
517*2d543d20SAndroid Build Coastguard Worker 		}
518*2d543d20SAndroid Build Coastguard Worker 	}
519*2d543d20SAndroid Build Coastguard Worker 
520*2d543d20SAndroid Build Coastguard Worker 	if (show_version) {
521*2d543d20SAndroid Build Coastguard Worker 		printf("%d (compatibility range %d-%d)\n",
522*2d543d20SAndroid Build Coastguard Worker 			   policyvers ? policyvers : POLICYDB_VERSION_MAX ,
523*2d543d20SAndroid Build Coastguard Worker 		       POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN);
524*2d543d20SAndroid Build Coastguard Worker 		exit(0);
525*2d543d20SAndroid Build Coastguard Worker 	}
526*2d543d20SAndroid Build Coastguard Worker 
527*2d543d20SAndroid Build Coastguard Worker 	if (optind != argc) {
528*2d543d20SAndroid Build Coastguard Worker 		file = argv[optind++];
529*2d543d20SAndroid Build Coastguard Worker 		if (optind != argc)
530*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
531*2d543d20SAndroid Build Coastguard Worker 	}
532*2d543d20SAndroid Build Coastguard Worker 	/* Set policydb and sidtab used by libsepol service functions
533*2d543d20SAndroid Build Coastguard Worker 	   to my structures, so that I can directly populate and
534*2d543d20SAndroid Build Coastguard Worker 	   manipulate them. */
535*2d543d20SAndroid Build Coastguard Worker 	sepol_set_policydb(&policydb);
536*2d543d20SAndroid Build Coastguard Worker 	sepol_set_sidtab(&sidtab);
537*2d543d20SAndroid Build Coastguard Worker 
538*2d543d20SAndroid Build Coastguard Worker 	if (cil && conf) {
539*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't convert to CIL and policy.conf at the same time\n");
540*2d543d20SAndroid Build Coastguard Worker 		exit(1);
541*2d543d20SAndroid Build Coastguard Worker 	}
542*2d543d20SAndroid Build Coastguard Worker 
543*2d543d20SAndroid Build Coastguard Worker 	if (binary) {
544*2d543d20SAndroid Build Coastguard Worker 		fd = open(file, O_RDONLY);
545*2d543d20SAndroid Build Coastguard Worker 		if (fd < 0) {
546*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Can't open '%s':  %s\n",
547*2d543d20SAndroid Build Coastguard Worker 				file, strerror(errno));
548*2d543d20SAndroid Build Coastguard Worker 			exit(1);
549*2d543d20SAndroid Build Coastguard Worker 		}
550*2d543d20SAndroid Build Coastguard Worker 		if (fstat(fd, &sb) < 0) {
551*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Can't stat '%s':  %s\n",
552*2d543d20SAndroid Build Coastguard Worker 				file, strerror(errno));
553*2d543d20SAndroid Build Coastguard Worker 			exit(1);
554*2d543d20SAndroid Build Coastguard Worker 		}
555*2d543d20SAndroid Build Coastguard Worker 		map =
556*2d543d20SAndroid Build Coastguard Worker 		    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
557*2d543d20SAndroid Build Coastguard Worker 			 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 				file, strerror(errno));
561*2d543d20SAndroid Build Coastguard Worker 			exit(1);
562*2d543d20SAndroid Build Coastguard Worker 		}
563*2d543d20SAndroid Build Coastguard Worker 		policy_file_init(&pf);
564*2d543d20SAndroid Build Coastguard Worker 		pf.type = PF_USE_MEMORY;
565*2d543d20SAndroid Build Coastguard Worker 		pf.data = map;
566*2d543d20SAndroid Build Coastguard Worker 		pf.len = sb.st_size;
567*2d543d20SAndroid Build Coastguard Worker 		if (policydb_init(&policydb)) {
568*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  policydb_init:  Out of memory!\n",
569*2d543d20SAndroid Build Coastguard Worker 				argv[0]);
570*2d543d20SAndroid Build Coastguard Worker 			exit(1);
571*2d543d20SAndroid Build Coastguard Worker 		}
572*2d543d20SAndroid Build Coastguard Worker 		ret = policydb_read(&policydb, &pf, 1);
573*2d543d20SAndroid Build Coastguard Worker 		if (ret) {
574*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr,
575*2d543d20SAndroid Build Coastguard Worker 				"%s:  error(s) encountered while parsing configuration\n",
576*2d543d20SAndroid Build Coastguard Worker 				argv[0]);
577*2d543d20SAndroid Build Coastguard Worker 			exit(1);
578*2d543d20SAndroid Build Coastguard Worker 		}
579*2d543d20SAndroid Build Coastguard Worker 		policydbp = &policydb;
580*2d543d20SAndroid Build Coastguard Worker 
581*2d543d20SAndroid Build Coastguard Worker 		/* Check Policy Consistency */
582*2d543d20SAndroid Build Coastguard Worker 		if (policydbp->mls) {
583*2d543d20SAndroid Build Coastguard Worker 			if (!mlspol) {
584*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  MLS policy, but non-MLS"
585*2d543d20SAndroid Build Coastguard Worker 					" is specified\n", argv[0]);
586*2d543d20SAndroid Build Coastguard Worker 				exit(1);
587*2d543d20SAndroid Build Coastguard Worker 			}
588*2d543d20SAndroid Build Coastguard Worker 		} else {
589*2d543d20SAndroid Build Coastguard Worker 			if (mlspol) {
590*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  non-MLS policy, but MLS"
591*2d543d20SAndroid Build Coastguard Worker 					" is specified\n", argv[0]);
592*2d543d20SAndroid Build Coastguard Worker 				exit(1);
593*2d543d20SAndroid Build Coastguard Worker 			}
594*2d543d20SAndroid Build Coastguard Worker 		}
595*2d543d20SAndroid Build Coastguard Worker 
596*2d543d20SAndroid Build Coastguard Worker 		if (policydbp->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
597*2d543d20SAndroid Build Coastguard Worker 			if (policyvers > policydbp->policyvers) {
598*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Binary policies with version <= %u cannot be upgraded\n", POLICYDB_VERSION_PERMISSIVE);
599*2d543d20SAndroid Build Coastguard Worker 			} else if (policyvers) {
600*2d543d20SAndroid Build Coastguard Worker 				policydbp->policyvers = policyvers;
601*2d543d20SAndroid Build Coastguard Worker 			}
602*2d543d20SAndroid Build Coastguard Worker 		} else {
603*2d543d20SAndroid Build Coastguard Worker 			policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX;
604*2d543d20SAndroid Build Coastguard Worker 		}
605*2d543d20SAndroid Build Coastguard Worker 	} else {
606*2d543d20SAndroid Build Coastguard Worker 		if (conf) {
607*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Can only generate policy.conf from binary policy\n");
608*2d543d20SAndroid Build Coastguard Worker 			exit(1);
609*2d543d20SAndroid Build Coastguard Worker 		}
610*2d543d20SAndroid Build Coastguard Worker 		if (policydb_init(&parse_policy))
611*2d543d20SAndroid Build Coastguard Worker 			exit(1);
612*2d543d20SAndroid Build Coastguard Worker 		/* We build this as a base policy first since that is all the parser understands */
613*2d543d20SAndroid Build Coastguard Worker 		parse_policy.policy_type = POLICY_BASE;
614*2d543d20SAndroid Build Coastguard Worker 		policydb_set_target_platform(&parse_policy, target);
615*2d543d20SAndroid Build Coastguard Worker 
616*2d543d20SAndroid Build Coastguard Worker 		/* Let sepol know if we are dealing with MLS support */
617*2d543d20SAndroid Build Coastguard Worker 		parse_policy.mls = mlspol;
618*2d543d20SAndroid Build Coastguard Worker 		parse_policy.handle_unknown = handle_unknown;
619*2d543d20SAndroid Build Coastguard Worker 		parse_policy.policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX;
620*2d543d20SAndroid Build Coastguard Worker 
621*2d543d20SAndroid Build Coastguard Worker 		policydbp = &parse_policy;
622*2d543d20SAndroid Build Coastguard Worker 
623*2d543d20SAndroid Build Coastguard Worker 		if (read_source_policy(policydbp, file, "checkpolicy") < 0)
624*2d543d20SAndroid Build Coastguard Worker 			exit(1);
625*2d543d20SAndroid Build Coastguard Worker 
626*2d543d20SAndroid Build Coastguard Worker 		if (hashtab_map(policydbp->p_levels.table, check_level, NULL))
627*2d543d20SAndroid Build Coastguard Worker 			exit(1);
628*2d543d20SAndroid Build Coastguard Worker 
629*2d543d20SAndroid Build Coastguard Worker 		/* Linking takes care of optional avrule blocks */
630*2d543d20SAndroid Build Coastguard Worker 		if (link_modules(NULL, policydbp, NULL, 0, 0)) {
631*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Error while resolving optionals\n");
632*2d543d20SAndroid Build Coastguard Worker 			exit(1);
633*2d543d20SAndroid Build Coastguard Worker 		}
634*2d543d20SAndroid Build Coastguard Worker 
635*2d543d20SAndroid Build Coastguard Worker 		if (!cil) {
636*2d543d20SAndroid Build Coastguard Worker 			if (policydb_init(&policydb)) {
637*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
638*2d543d20SAndroid Build Coastguard Worker 				exit(1);
639*2d543d20SAndroid Build Coastguard Worker 			}
640*2d543d20SAndroid Build Coastguard Worker 			if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, !disable_neverallow)) {
641*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Error while expanding policy\n");
642*2d543d20SAndroid Build Coastguard Worker 				exit(1);
643*2d543d20SAndroid Build Coastguard Worker 			}
644*2d543d20SAndroid Build Coastguard Worker 			policydb.policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX;
645*2d543d20SAndroid Build Coastguard Worker 			policydb_destroy(policydbp);
646*2d543d20SAndroid Build Coastguard Worker 			policydbp = &policydb;
647*2d543d20SAndroid Build Coastguard Worker 		}
648*2d543d20SAndroid Build Coastguard Worker 	}
649*2d543d20SAndroid Build Coastguard Worker 
650*2d543d20SAndroid Build Coastguard Worker 	if (policydb_load_isids(&policydb, &sidtab))
651*2d543d20SAndroid Build Coastguard Worker 		exit(1);
652*2d543d20SAndroid Build Coastguard Worker 
653*2d543d20SAndroid Build Coastguard Worker 	if (optimize && policydbp->policy_type == POLICY_KERN) {
654*2d543d20SAndroid Build Coastguard Worker 		ret = policydb_optimize(policydbp);
655*2d543d20SAndroid Build Coastguard Worker 		if (ret) {
656*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  error optimizing policy\n", argv[0]);
657*2d543d20SAndroid Build Coastguard Worker 			exit(1);
658*2d543d20SAndroid Build Coastguard Worker 		}
659*2d543d20SAndroid Build Coastguard Worker 	}
660*2d543d20SAndroid Build Coastguard Worker 
661*2d543d20SAndroid Build Coastguard Worker 	if (outfile) {
662*2d543d20SAndroid Build Coastguard Worker 		if (!strcmp(outfile, "-")) {
663*2d543d20SAndroid Build Coastguard Worker 			outfp = stdout;
664*2d543d20SAndroid Build Coastguard Worker 			outfile = "<STDOUT>";
665*2d543d20SAndroid Build Coastguard Worker 		} else {
666*2d543d20SAndroid Build Coastguard Worker 			outfp = fopen(outfile, "w");
667*2d543d20SAndroid Build Coastguard Worker 			if (!outfp) {
668*2d543d20SAndroid Build Coastguard Worker 				perror(outfile);
669*2d543d20SAndroid Build Coastguard Worker 				exit(1);
670*2d543d20SAndroid Build Coastguard Worker 			}
671*2d543d20SAndroid Build Coastguard Worker 		}
672*2d543d20SAndroid Build Coastguard Worker 
673*2d543d20SAndroid Build Coastguard Worker 		if (!cil) {
674*2d543d20SAndroid Build Coastguard Worker 			if (!conf) {
675*2d543d20SAndroid Build Coastguard Worker 				policydb.policy_type = POLICY_KERN;
676*2d543d20SAndroid Build Coastguard Worker 
677*2d543d20SAndroid Build Coastguard Worker 				policy_file_init(&pf);
678*2d543d20SAndroid Build Coastguard Worker 				pf.type = PF_USE_STDIO;
679*2d543d20SAndroid Build Coastguard Worker 				pf.fp = outfp;
680*2d543d20SAndroid Build Coastguard Worker 				if (sort) {
681*2d543d20SAndroid Build Coastguard Worker 					ret = policydb_sort_ocontexts(&policydb);
682*2d543d20SAndroid Build Coastguard Worker 					if (ret) {
683*2d543d20SAndroid Build Coastguard Worker 						fprintf(stderr, "%s:  error sorting ocontexts\n",
684*2d543d20SAndroid Build Coastguard Worker 						argv[0]);
685*2d543d20SAndroid Build Coastguard Worker 						exit(1);
686*2d543d20SAndroid Build Coastguard Worker 					}
687*2d543d20SAndroid Build Coastguard Worker 				}
688*2d543d20SAndroid Build Coastguard Worker 				ret = policydb_write(&policydb, &pf);
689*2d543d20SAndroid Build Coastguard Worker 			} else {
690*2d543d20SAndroid Build Coastguard Worker 				ret = sepol_kernel_policydb_to_conf(outfp, policydbp);
691*2d543d20SAndroid Build Coastguard Worker 			}
692*2d543d20SAndroid Build Coastguard Worker 			if (ret) {
693*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  error writing %s\n",
694*2d543d20SAndroid Build Coastguard Worker 						argv[0], outfile);
695*2d543d20SAndroid Build Coastguard Worker 				exit(1);
696*2d543d20SAndroid Build Coastguard Worker 			}
697*2d543d20SAndroid Build Coastguard Worker 		} else {
698*2d543d20SAndroid Build Coastguard Worker 			if (binary) {
699*2d543d20SAndroid Build Coastguard Worker 				ret = sepol_kernel_policydb_to_cil(outfp, policydbp);
700*2d543d20SAndroid Build Coastguard Worker 			} else {
701*2d543d20SAndroid Build Coastguard Worker 				ret = sepol_module_policydb_to_cil(outfp, policydbp, 1);
702*2d543d20SAndroid Build Coastguard Worker 			}
703*2d543d20SAndroid Build Coastguard Worker 			if (ret) {
704*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  error writing %s\n", argv[0], outfile);
705*2d543d20SAndroid Build Coastguard Worker 				exit(1);
706*2d543d20SAndroid Build Coastguard Worker 			}
707*2d543d20SAndroid Build Coastguard Worker 		}
708*2d543d20SAndroid Build Coastguard Worker 
709*2d543d20SAndroid Build Coastguard Worker 		if (outfp != stdout) {
710*2d543d20SAndroid Build Coastguard Worker 			if(fclose(outfp)) {
711*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  error closing %s:  %s\n", argv[0], outfile, strerror(errno));
712*2d543d20SAndroid Build Coastguard Worker 				exit(1);
713*2d543d20SAndroid Build Coastguard Worker 			}
714*2d543d20SAndroid Build Coastguard Worker 		}
715*2d543d20SAndroid Build Coastguard Worker 	} else if (cil) {
716*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  No file to write CIL was specified\n", argv[0]);
717*2d543d20SAndroid Build Coastguard Worker 		exit(1);
718*2d543d20SAndroid Build Coastguard Worker 	}
719*2d543d20SAndroid Build Coastguard Worker 
720*2d543d20SAndroid Build Coastguard Worker 	if (!debug) {
721*2d543d20SAndroid Build Coastguard Worker 		policydb_destroy(&policydb);
722*2d543d20SAndroid Build Coastguard Worker 		sepol_sidtab_destroy(&sidtab);
723*2d543d20SAndroid Build Coastguard Worker 		exit(0);
724*2d543d20SAndroid Build Coastguard Worker 	}
725*2d543d20SAndroid Build Coastguard Worker 
726*2d543d20SAndroid Build Coastguard Worker       menu:
727*2d543d20SAndroid Build Coastguard Worker 	printf("\nSelect an option:\n");
728*2d543d20SAndroid Build Coastguard Worker 	printf("0)  Call compute_access_vector\n");
729*2d543d20SAndroid Build Coastguard Worker 	printf("1)  Call sid_to_context\n");
730*2d543d20SAndroid Build Coastguard Worker 	printf("2)  Call context_to_sid\n");
731*2d543d20SAndroid Build Coastguard Worker 	printf("3)  Call transition_sid\n");
732*2d543d20SAndroid Build Coastguard Worker 	printf("4)  Call member_sid\n");
733*2d543d20SAndroid Build Coastguard Worker 	printf("5)  Call change_sid\n");
734*2d543d20SAndroid Build Coastguard Worker 	printf("6)  Call list_sids\n");
735*2d543d20SAndroid Build Coastguard Worker 	printf("7)  Call load_policy\n");
736*2d543d20SAndroid Build Coastguard Worker 	printf("8)  Call fs_sid\n");
737*2d543d20SAndroid Build Coastguard Worker 	printf("9)  Call port_sid\n");
738*2d543d20SAndroid Build Coastguard Worker 	printf("a)  Call netif_sid\n");
739*2d543d20SAndroid Build Coastguard Worker 	printf("b)  Call node_sid\n");
740*2d543d20SAndroid Build Coastguard Worker 	printf("c)  Call fs_use\n");
741*2d543d20SAndroid Build Coastguard Worker 	printf("d)  Call genfs_sid\n");
742*2d543d20SAndroid Build Coastguard Worker 	printf("e)  Call get_user_sids\n");
743*2d543d20SAndroid Build Coastguard Worker 	printf("f)  display conditional bools\n");
744*2d543d20SAndroid Build Coastguard Worker 	printf("g)  display conditional expressions\n");
745*2d543d20SAndroid Build Coastguard Worker 	printf("h)  change a boolean value\n");
746*2d543d20SAndroid Build Coastguard Worker 	printf("i)  display constraint expressions\n");
747*2d543d20SAndroid Build Coastguard Worker 	printf("j)  display validatetrans expressions\n");
748*2d543d20SAndroid Build Coastguard Worker 	printf("k)  Call ibpkey_sid\n");
749*2d543d20SAndroid Build Coastguard Worker 	printf("l)  Call ibendport_sid\n");
750*2d543d20SAndroid Build Coastguard Worker #ifdef EQUIVTYPES
751*2d543d20SAndroid Build Coastguard Worker 	printf("z)  Show equivalent types\n");
752*2d543d20SAndroid Build Coastguard Worker #endif
753*2d543d20SAndroid Build Coastguard Worker 	printf("m)  Show menu again\n");
754*2d543d20SAndroid Build Coastguard Worker 	printf("q)  Exit\n");
755*2d543d20SAndroid Build Coastguard Worker 	while (1) {
756*2d543d20SAndroid Build Coastguard Worker 		printf("\nChoose:  ");
757*2d543d20SAndroid Build Coastguard Worker 		FGETS(ans, sizeof(ans), stdin);
758*2d543d20SAndroid Build Coastguard Worker 		switch (ans[0]) {
759*2d543d20SAndroid Build Coastguard Worker 		case '0':
760*2d543d20SAndroid Build Coastguard Worker 			printf("source sid?  ");
761*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
762*2d543d20SAndroid Build Coastguard Worker 			ssid = atoi(ans);
763*2d543d20SAndroid Build Coastguard Worker 
764*2d543d20SAndroid Build Coastguard Worker 			printf("target sid?  ");
765*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
766*2d543d20SAndroid Build Coastguard Worker 			tsid = atoi(ans);
767*2d543d20SAndroid Build Coastguard Worker 
768*2d543d20SAndroid Build Coastguard Worker 			printf("target class?  ");
769*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
770*2d543d20SAndroid Build Coastguard Worker 			if (isdigit(ans[0])) {
771*2d543d20SAndroid Build Coastguard Worker 				tclass = atoi(ans);
772*2d543d20SAndroid Build Coastguard Worker 				if (!tclass
773*2d543d20SAndroid Build Coastguard Worker 				    || tclass > policydb.p_classes.nprim) {
774*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class.\n");
775*2d543d20SAndroid Build Coastguard Worker 					break;
776*2d543d20SAndroid Build Coastguard Worker 				}
777*2d543d20SAndroid Build Coastguard Worker 				cladatum =
778*2d543d20SAndroid Build Coastguard Worker 				    policydb.class_val_to_struct[tclass - 1];
779*2d543d20SAndroid Build Coastguard Worker 			} else {
780*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
781*2d543d20SAndroid Build Coastguard Worker 				cladatum =
782*2d543d20SAndroid Build Coastguard Worker 				    (class_datum_t *) hashtab_search(policydb.
783*2d543d20SAndroid Build Coastguard Worker 								     p_classes.
784*2d543d20SAndroid Build Coastguard Worker 								     table,
785*2d543d20SAndroid Build Coastguard Worker 								     ans);
786*2d543d20SAndroid Build Coastguard Worker 				if (!cladatum) {
787*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class\n");
788*2d543d20SAndroid Build Coastguard Worker 					break;
789*2d543d20SAndroid Build Coastguard Worker 				}
790*2d543d20SAndroid Build Coastguard Worker 				tclass = cladatum->s.value;
791*2d543d20SAndroid Build Coastguard Worker 			}
792*2d543d20SAndroid Build Coastguard Worker 
793*2d543d20SAndroid Build Coastguard Worker 			if (!cladatum->comdatum && !cladatum->permissions.nprim) {
794*2d543d20SAndroid Build Coastguard Worker 				printf
795*2d543d20SAndroid Build Coastguard Worker 				    ("\nNo access vector definition for that class\n");
796*2d543d20SAndroid Build Coastguard Worker 				break;
797*2d543d20SAndroid Build Coastguard Worker 			}
798*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_compute_av(ssid, tsid, tclass, 0, &avd);
799*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
800*2d543d20SAndroid Build Coastguard Worker 			case 0:
801*2d543d20SAndroid Build Coastguard Worker 				printf("\nallowed {");
802*2d543d20SAndroid Build Coastguard Worker 				for (i = 1; i <= sizeof(avd.allowed) * 8; i++) {
803*2d543d20SAndroid Build Coastguard Worker 					if (avd.allowed & (UINT32_C(1) << (i - 1))) {
804*2d543d20SAndroid Build Coastguard Worker 						v.val = i;
805*2d543d20SAndroid Build Coastguard Worker 						ret =
806*2d543d20SAndroid Build Coastguard Worker 						    hashtab_map(cladatum->
807*2d543d20SAndroid Build Coastguard Worker 								permissions.
808*2d543d20SAndroid Build Coastguard Worker 								table,
809*2d543d20SAndroid Build Coastguard Worker 								find_perm, &v);
810*2d543d20SAndroid Build Coastguard Worker 						if (!ret && cladatum->comdatum) {
811*2d543d20SAndroid Build Coastguard Worker 							ret =
812*2d543d20SAndroid Build Coastguard Worker 							    hashtab_map
813*2d543d20SAndroid Build Coastguard Worker 							    (cladatum->
814*2d543d20SAndroid Build Coastguard Worker 							     comdatum->
815*2d543d20SAndroid Build Coastguard Worker 							     permissions.table,
816*2d543d20SAndroid Build Coastguard Worker 							     find_perm, &v);
817*2d543d20SAndroid Build Coastguard Worker 						}
818*2d543d20SAndroid Build Coastguard Worker 						if (ret)
819*2d543d20SAndroid Build Coastguard Worker 							printf(" %s", v.name);
820*2d543d20SAndroid Build Coastguard Worker 					}
821*2d543d20SAndroid Build Coastguard Worker 				}
822*2d543d20SAndroid Build Coastguard Worker 				printf(" }\n");
823*2d543d20SAndroid Build Coastguard Worker 				break;
824*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
825*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid sid\n");
826*2d543d20SAndroid Build Coastguard Worker 				break;
827*2d543d20SAndroid Build Coastguard Worker 			default:
828*2d543d20SAndroid Build Coastguard Worker 				printf("return code 0x%x\n", ret);
829*2d543d20SAndroid Build Coastguard Worker 			}
830*2d543d20SAndroid Build Coastguard Worker 			break;
831*2d543d20SAndroid Build Coastguard Worker 		case '1':
832*2d543d20SAndroid Build Coastguard Worker 			printf("sid?  ");
833*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
834*2d543d20SAndroid Build Coastguard Worker 			ssid = atoi(ans);
835*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_sid_to_context(ssid,
836*2d543d20SAndroid Build Coastguard Worker 						   &scontext, &scontext_len);
837*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
838*2d543d20SAndroid Build Coastguard Worker 			case 0:
839*2d543d20SAndroid Build Coastguard Worker 				printf("\nscontext %s\n", scontext);
840*2d543d20SAndroid Build Coastguard Worker 				free(scontext);
841*2d543d20SAndroid Build Coastguard Worker 				break;
842*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
843*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid sid\n");
844*2d543d20SAndroid Build Coastguard Worker 				break;
845*2d543d20SAndroid Build Coastguard Worker 			case -ENOMEM:
846*2d543d20SAndroid Build Coastguard Worker 				printf("\nout of memory\n");
847*2d543d20SAndroid Build Coastguard Worker 				break;
848*2d543d20SAndroid Build Coastguard Worker 			default:
849*2d543d20SAndroid Build Coastguard Worker 				printf("return code 0x%x\n", ret);
850*2d543d20SAndroid Build Coastguard Worker 			}
851*2d543d20SAndroid Build Coastguard Worker 			break;
852*2d543d20SAndroid Build Coastguard Worker 		case '2':
853*2d543d20SAndroid Build Coastguard Worker 			printf("scontext?  ");
854*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
855*2d543d20SAndroid Build Coastguard Worker 			scontext_len = strlen(ans);
856*2d543d20SAndroid Build Coastguard Worker 			ans[scontext_len - 1] = 0;
857*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_context_to_sid(ans, scontext_len, &ssid);
858*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
859*2d543d20SAndroid Build Coastguard Worker 			case 0:
860*2d543d20SAndroid Build Coastguard Worker 				printf("\nsid %d\n", ssid);
861*2d543d20SAndroid Build Coastguard Worker 				break;
862*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
863*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid context\n");
864*2d543d20SAndroid Build Coastguard Worker 				break;
865*2d543d20SAndroid Build Coastguard Worker 			case -ENOMEM:
866*2d543d20SAndroid Build Coastguard Worker 				printf("\nout of memory\n");
867*2d543d20SAndroid Build Coastguard Worker 				break;
868*2d543d20SAndroid Build Coastguard Worker 			default:
869*2d543d20SAndroid Build Coastguard Worker 				printf("return code 0x%x\n", ret);
870*2d543d20SAndroid Build Coastguard Worker 			}
871*2d543d20SAndroid Build Coastguard Worker 			break;
872*2d543d20SAndroid Build Coastguard Worker 		case '3':
873*2d543d20SAndroid Build Coastguard Worker 		case '4':
874*2d543d20SAndroid Build Coastguard Worker 		case '5':
875*2d543d20SAndroid Build Coastguard Worker 			ch = ans[0];
876*2d543d20SAndroid Build Coastguard Worker 
877*2d543d20SAndroid Build Coastguard Worker 			printf("source sid?  ");
878*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
879*2d543d20SAndroid Build Coastguard Worker 			ssid = atoi(ans);
880*2d543d20SAndroid Build Coastguard Worker 			printf("target sid?  ");
881*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
882*2d543d20SAndroid Build Coastguard Worker 			tsid = atoi(ans);
883*2d543d20SAndroid Build Coastguard Worker 
884*2d543d20SAndroid Build Coastguard Worker 			printf("object class?  ");
885*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
886*2d543d20SAndroid Build Coastguard Worker 			if (isdigit(ans[0])) {
887*2d543d20SAndroid Build Coastguard Worker 				tclass = atoi(ans);
888*2d543d20SAndroid Build Coastguard Worker 				if (!tclass
889*2d543d20SAndroid Build Coastguard Worker 				    || tclass > policydb.p_classes.nprim) {
890*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class.\n");
891*2d543d20SAndroid Build Coastguard Worker 					break;
892*2d543d20SAndroid Build Coastguard Worker 				}
893*2d543d20SAndroid Build Coastguard Worker 			} else {
894*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
895*2d543d20SAndroid Build Coastguard Worker 				cladatum =
896*2d543d20SAndroid Build Coastguard Worker 				    (class_datum_t *) hashtab_search(policydb.
897*2d543d20SAndroid Build Coastguard Worker 								     p_classes.
898*2d543d20SAndroid Build Coastguard Worker 								     table,
899*2d543d20SAndroid Build Coastguard Worker 								     ans);
900*2d543d20SAndroid Build Coastguard Worker 				if (!cladatum) {
901*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class\n");
902*2d543d20SAndroid Build Coastguard Worker 					break;
903*2d543d20SAndroid Build Coastguard Worker 				}
904*2d543d20SAndroid Build Coastguard Worker 				tclass = cladatum->s.value;
905*2d543d20SAndroid Build Coastguard Worker 			}
906*2d543d20SAndroid Build Coastguard Worker 
907*2d543d20SAndroid Build Coastguard Worker 			if (ch == '3')
908*2d543d20SAndroid Build Coastguard Worker 				ret =
909*2d543d20SAndroid Build Coastguard Worker 				    sepol_transition_sid(ssid, tsid, tclass,
910*2d543d20SAndroid Build Coastguard Worker 							 &ssid);
911*2d543d20SAndroid Build Coastguard Worker 			else if (ch == '4')
912*2d543d20SAndroid Build Coastguard Worker 				ret =
913*2d543d20SAndroid Build Coastguard Worker 				    sepol_member_sid(ssid, tsid, tclass, &ssid);
914*2d543d20SAndroid Build Coastguard Worker 			else
915*2d543d20SAndroid Build Coastguard Worker 				ret =
916*2d543d20SAndroid Build Coastguard Worker 				    sepol_change_sid(ssid, tsid, tclass, &ssid);
917*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
918*2d543d20SAndroid Build Coastguard Worker 			case 0:
919*2d543d20SAndroid Build Coastguard Worker 				printf("\nsid %d\n", ssid);
920*2d543d20SAndroid Build Coastguard Worker 				break;
921*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
922*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid sid\n");
923*2d543d20SAndroid Build Coastguard Worker 				break;
924*2d543d20SAndroid Build Coastguard Worker 			case -ENOMEM:
925*2d543d20SAndroid Build Coastguard Worker 				printf("\nout of memory\n");
926*2d543d20SAndroid Build Coastguard Worker 				break;
927*2d543d20SAndroid Build Coastguard Worker 			default:
928*2d543d20SAndroid Build Coastguard Worker 				printf("return code 0x%x\n", ret);
929*2d543d20SAndroid Build Coastguard Worker 			}
930*2d543d20SAndroid Build Coastguard Worker 			break;
931*2d543d20SAndroid Build Coastguard Worker 		case '6':
932*2d543d20SAndroid Build Coastguard Worker 			sepol_sidtab_map(&sidtab, print_sid, 0);
933*2d543d20SAndroid Build Coastguard Worker 			break;
934*2d543d20SAndroid Build Coastguard Worker 		case '7':
935*2d543d20SAndroid Build Coastguard Worker 			printf("pathname?  ");
936*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
937*2d543d20SAndroid Build Coastguard Worker 			pathlen = strlen(ans);
938*2d543d20SAndroid Build Coastguard Worker 			ans[pathlen - 1] = 0;
939*2d543d20SAndroid Build Coastguard Worker 			fd = open(ans, O_RDONLY);
940*2d543d20SAndroid Build Coastguard Worker 			if (fd < 0) {
941*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Can't open '%s':  %s\n",
942*2d543d20SAndroid Build Coastguard Worker 					ans, strerror(errno));
943*2d543d20SAndroid Build Coastguard Worker 				break;
944*2d543d20SAndroid Build Coastguard Worker 			}
945*2d543d20SAndroid Build Coastguard Worker 			if (fstat(fd, &sb) < 0) {
946*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Can't stat '%s':  %s\n",
947*2d543d20SAndroid Build Coastguard Worker 					ans, strerror(errno));
948*2d543d20SAndroid Build Coastguard Worker 				break;
949*2d543d20SAndroid Build Coastguard Worker 			}
950*2d543d20SAndroid Build Coastguard Worker 			map =
951*2d543d20SAndroid Build Coastguard Worker 			    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
952*2d543d20SAndroid Build Coastguard Worker 				 MAP_PRIVATE, fd, 0);
953*2d543d20SAndroid Build Coastguard Worker 			if (map == MAP_FAILED) {
954*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "Can't map '%s':  %s\n",
955*2d543d20SAndroid Build Coastguard Worker 					ans, strerror(errno));
956*2d543d20SAndroid Build Coastguard Worker 				break;
957*2d543d20SAndroid Build Coastguard Worker 			}
958*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_load_policy(map, sb.st_size);
959*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
960*2d543d20SAndroid Build Coastguard Worker 			case 0:
961*2d543d20SAndroid Build Coastguard Worker 				printf("\nsuccess\n");
962*2d543d20SAndroid Build Coastguard Worker 				break;
963*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
964*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid policy\n");
965*2d543d20SAndroid Build Coastguard Worker 				break;
966*2d543d20SAndroid Build Coastguard Worker 			case -ENOMEM:
967*2d543d20SAndroid Build Coastguard Worker 				printf("\nout of memory\n");
968*2d543d20SAndroid Build Coastguard Worker 				break;
969*2d543d20SAndroid Build Coastguard Worker 			default:
970*2d543d20SAndroid Build Coastguard Worker 				printf("return code 0x%x\n", ret);
971*2d543d20SAndroid Build Coastguard Worker 			}
972*2d543d20SAndroid Build Coastguard Worker 			break;
973*2d543d20SAndroid Build Coastguard Worker 		case '8':
974*2d543d20SAndroid Build Coastguard Worker 			printf("fs kdevname?  ");
975*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
976*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
977*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_fs_sid(ans, &ssid, &tsid);
978*2d543d20SAndroid Build Coastguard Worker 			if (ret) {
979*2d543d20SAndroid Build Coastguard Worker 				printf("unknown fs kdevname\n");
980*2d543d20SAndroid Build Coastguard Worker 			} else {
981*2d543d20SAndroid Build Coastguard Worker 				printf("fs_sid %d default_file_sid %d\n", ssid, tsid);
982*2d543d20SAndroid Build Coastguard Worker 			}
983*2d543d20SAndroid Build Coastguard Worker 			break;
984*2d543d20SAndroid Build Coastguard Worker 		case '9':
985*2d543d20SAndroid Build Coastguard Worker 			printf("protocol?  ");
986*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
987*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
988*2d543d20SAndroid Build Coastguard Worker 			if (!strcmp(ans, "tcp") || !strcmp(ans, "TCP"))
989*2d543d20SAndroid Build Coastguard Worker 				protocol = IPPROTO_TCP;
990*2d543d20SAndroid Build Coastguard Worker 			else if (!strcmp(ans, "udp") || !strcmp(ans, "UDP"))
991*2d543d20SAndroid Build Coastguard Worker 				protocol = IPPROTO_UDP;
992*2d543d20SAndroid Build Coastguard Worker 			else if (!strcmp(ans, "dccp") || !strcmp(ans, "DCCP"))
993*2d543d20SAndroid Build Coastguard Worker 				protocol = IPPROTO_DCCP;
994*2d543d20SAndroid Build Coastguard Worker 			else if (!strcmp(ans, "sctp") || !strcmp(ans, "SCTP"))
995*2d543d20SAndroid Build Coastguard Worker 				protocol = IPPROTO_SCTP;
996*2d543d20SAndroid Build Coastguard Worker 			else {
997*2d543d20SAndroid Build Coastguard Worker 				printf("unknown protocol\n");
998*2d543d20SAndroid Build Coastguard Worker 				break;
999*2d543d20SAndroid Build Coastguard Worker 			}
1000*2d543d20SAndroid Build Coastguard Worker 			printf("port? ");
1001*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1002*2d543d20SAndroid Build Coastguard Worker 			port = atoi(ans);
1003*2d543d20SAndroid Build Coastguard Worker 			sepol_port_sid(0, 0, protocol, port, &ssid);
1004*2d543d20SAndroid Build Coastguard Worker 			printf("sid %d\n", ssid);
1005*2d543d20SAndroid Build Coastguard Worker 			break;
1006*2d543d20SAndroid Build Coastguard Worker 		case 'a':
1007*2d543d20SAndroid Build Coastguard Worker 			printf("netif name?  ");
1008*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1009*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1010*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_netif_sid(ans, &ssid, &tsid);
1011*2d543d20SAndroid Build Coastguard Worker 			if (ret) {
1012*2d543d20SAndroid Build Coastguard Worker 				printf("unknown name\n");
1013*2d543d20SAndroid Build Coastguard Worker 			} else {
1014*2d543d20SAndroid Build Coastguard Worker 				printf("if_sid %d default_msg_sid %d\n", ssid, tsid);
1015*2d543d20SAndroid Build Coastguard Worker 			}
1016*2d543d20SAndroid Build Coastguard Worker 			break;
1017*2d543d20SAndroid Build Coastguard Worker 		case 'b':{
1018*2d543d20SAndroid Build Coastguard Worker 				char *p;
1019*2d543d20SAndroid Build Coastguard Worker 				int family, len;
1020*2d543d20SAndroid Build Coastguard Worker 				struct in_addr addr4;
1021*2d543d20SAndroid Build Coastguard Worker 				struct in6_addr addr6;
1022*2d543d20SAndroid Build Coastguard Worker 
1023*2d543d20SAndroid Build Coastguard Worker 				printf("protocol family? ");
1024*2d543d20SAndroid Build Coastguard Worker 				FGETS(ans, sizeof(ans), stdin);
1025*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1026*2d543d20SAndroid Build Coastguard Worker 				if (!strcasecmp(ans, "ipv4"))
1027*2d543d20SAndroid Build Coastguard Worker 					family = AF_INET;
1028*2d543d20SAndroid Build Coastguard Worker 				else if (!strcasecmp(ans, "ipv6"))
1029*2d543d20SAndroid Build Coastguard Worker 					family = AF_INET6;
1030*2d543d20SAndroid Build Coastguard Worker 				else {
1031*2d543d20SAndroid Build Coastguard Worker 					printf("unknown protocol family\n");
1032*2d543d20SAndroid Build Coastguard Worker 					break;
1033*2d543d20SAndroid Build Coastguard Worker 				}
1034*2d543d20SAndroid Build Coastguard Worker 
1035*2d543d20SAndroid Build Coastguard Worker 				printf("node address?  ");
1036*2d543d20SAndroid Build Coastguard Worker 				FGETS(ans, sizeof(ans), stdin);
1037*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1038*2d543d20SAndroid Build Coastguard Worker 
1039*2d543d20SAndroid Build Coastguard Worker 				if (family == AF_INET) {
1040*2d543d20SAndroid Build Coastguard Worker 					p = (char *)&addr4;
1041*2d543d20SAndroid Build Coastguard Worker 					len = sizeof(addr4);
1042*2d543d20SAndroid Build Coastguard Worker 				} else {
1043*2d543d20SAndroid Build Coastguard Worker 					p = (char *)&addr6;
1044*2d543d20SAndroid Build Coastguard Worker 					len = sizeof(addr6);
1045*2d543d20SAndroid Build Coastguard Worker 				}
1046*2d543d20SAndroid Build Coastguard Worker 
1047*2d543d20SAndroid Build Coastguard Worker 				if (inet_pton(family, ans, p) < 1) {
1048*2d543d20SAndroid Build Coastguard Worker 					printf("error parsing address\n");
1049*2d543d20SAndroid Build Coastguard Worker 					break;
1050*2d543d20SAndroid Build Coastguard Worker 				}
1051*2d543d20SAndroid Build Coastguard Worker 
1052*2d543d20SAndroid Build Coastguard Worker 				sepol_node_sid(family, p, len, &ssid);
1053*2d543d20SAndroid Build Coastguard Worker 				printf("sid %d\n", ssid);
1054*2d543d20SAndroid Build Coastguard Worker 				break;
1055*2d543d20SAndroid Build Coastguard Worker 			}
1056*2d543d20SAndroid Build Coastguard Worker 		case 'c':
1057*2d543d20SAndroid Build Coastguard Worker 			printf("fstype?  ");
1058*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1059*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1060*2d543d20SAndroid Build Coastguard Worker 			sepol_fs_use(ans, &uret, &ssid);
1061*2d543d20SAndroid Build Coastguard Worker 			switch (uret) {
1062*2d543d20SAndroid Build Coastguard Worker 			case SECURITY_FS_USE_XATTR:
1063*2d543d20SAndroid Build Coastguard Worker 				printf("use xattr\n");
1064*2d543d20SAndroid Build Coastguard Worker 				break;
1065*2d543d20SAndroid Build Coastguard Worker 			case SECURITY_FS_USE_TRANS:
1066*2d543d20SAndroid Build Coastguard Worker 				printf("use transition SIDs\n");
1067*2d543d20SAndroid Build Coastguard Worker 				break;
1068*2d543d20SAndroid Build Coastguard Worker 			case SECURITY_FS_USE_TASK:
1069*2d543d20SAndroid Build Coastguard Worker 				printf("use task SIDs\n");
1070*2d543d20SAndroid Build Coastguard Worker 				break;
1071*2d543d20SAndroid Build Coastguard Worker 			case SECURITY_FS_USE_GENFS:
1072*2d543d20SAndroid Build Coastguard Worker 				printf("use genfs\n");
1073*2d543d20SAndroid Build Coastguard Worker 				break;
1074*2d543d20SAndroid Build Coastguard Worker 			case SECURITY_FS_USE_NONE:
1075*2d543d20SAndroid Build Coastguard Worker 				printf("no labeling support\n");
1076*2d543d20SAndroid Build Coastguard Worker 				break;
1077*2d543d20SAndroid Build Coastguard Worker 			}
1078*2d543d20SAndroid Build Coastguard Worker 			printf("sid %d\n", ssid);
1079*2d543d20SAndroid Build Coastguard Worker 			break;
1080*2d543d20SAndroid Build Coastguard Worker 		case 'd':
1081*2d543d20SAndroid Build Coastguard Worker 			printf("fstype?  ");
1082*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1083*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1084*2d543d20SAndroid Build Coastguard Worker 			fstype = strdup(ans);
1085*2d543d20SAndroid Build Coastguard Worker 			printf("path?  ");
1086*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1087*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1088*2d543d20SAndroid Build Coastguard Worker 			path = strdup(ans);
1089*2d543d20SAndroid Build Coastguard Worker 			printf("object class?  ");
1090*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1091*2d543d20SAndroid Build Coastguard Worker 			if (isdigit(ans[0])) {
1092*2d543d20SAndroid Build Coastguard Worker 				tclass = atoi(ans);
1093*2d543d20SAndroid Build Coastguard Worker 				if (!tclass
1094*2d543d20SAndroid Build Coastguard Worker 				    || tclass > policydb.p_classes.nprim) {
1095*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class.\n");
1096*2d543d20SAndroid Build Coastguard Worker 					break;
1097*2d543d20SAndroid Build Coastguard Worker 				}
1098*2d543d20SAndroid Build Coastguard Worker 			} else {
1099*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1100*2d543d20SAndroid Build Coastguard Worker 				cladatum =
1101*2d543d20SAndroid Build Coastguard Worker 				    (class_datum_t *) hashtab_search(policydb.
1102*2d543d20SAndroid Build Coastguard Worker 								     p_classes.
1103*2d543d20SAndroid Build Coastguard Worker 								     table,
1104*2d543d20SAndroid Build Coastguard Worker 								     ans);
1105*2d543d20SAndroid Build Coastguard Worker 				if (!cladatum) {
1106*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class\n");
1107*2d543d20SAndroid Build Coastguard Worker 					break;
1108*2d543d20SAndroid Build Coastguard Worker 				}
1109*2d543d20SAndroid Build Coastguard Worker 				tclass = cladatum->s.value;
1110*2d543d20SAndroid Build Coastguard Worker 			}
1111*2d543d20SAndroid Build Coastguard Worker 			sepol_genfs_sid(fstype, path, tclass, &ssid);
1112*2d543d20SAndroid Build Coastguard Worker 			printf("sid %d\n", ssid);
1113*2d543d20SAndroid Build Coastguard Worker 			free(fstype);
1114*2d543d20SAndroid Build Coastguard Worker 			free(path);
1115*2d543d20SAndroid Build Coastguard Worker 			break;
1116*2d543d20SAndroid Build Coastguard Worker 		case 'e':
1117*2d543d20SAndroid Build Coastguard Worker 			printf("from SID?  ");
1118*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1119*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1120*2d543d20SAndroid Build Coastguard Worker 			ssid = atoi(ans);
1121*2d543d20SAndroid Build Coastguard Worker 
1122*2d543d20SAndroid Build Coastguard Worker 			printf("username?  ");
1123*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1124*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1125*2d543d20SAndroid Build Coastguard Worker 
1126*2d543d20SAndroid Build Coastguard Worker 			ret = sepol_get_user_sids(ssid, ans, &sids, &nel);
1127*2d543d20SAndroid Build Coastguard Worker 			switch (ret) {
1128*2d543d20SAndroid Build Coastguard Worker 			case 0:
1129*2d543d20SAndroid Build Coastguard Worker 				if (!nel)
1130*2d543d20SAndroid Build Coastguard Worker 					printf("\nnone\n");
1131*2d543d20SAndroid Build Coastguard Worker 				for (i = 0; i < nel; i++)
1132*2d543d20SAndroid Build Coastguard Worker 					print_sid(sids[i], NULL, NULL);
1133*2d543d20SAndroid Build Coastguard Worker 				free(sids);
1134*2d543d20SAndroid Build Coastguard Worker 				break;
1135*2d543d20SAndroid Build Coastguard Worker 			case -ENOMEM:
1136*2d543d20SAndroid Build Coastguard Worker 				printf("\nout of memory\n");
1137*2d543d20SAndroid Build Coastguard Worker 				break;
1138*2d543d20SAndroid Build Coastguard Worker 			case -EINVAL:
1139*2d543d20SAndroid Build Coastguard Worker 				printf("\ninvalid argument\n");
1140*2d543d20SAndroid Build Coastguard Worker 				break;
1141*2d543d20SAndroid Build Coastguard Worker 			default:
1142*2d543d20SAndroid Build Coastguard Worker 				printf("\nerror\n");
1143*2d543d20SAndroid Build Coastguard Worker 				break;
1144*2d543d20SAndroid Build Coastguard Worker 			}
1145*2d543d20SAndroid Build Coastguard Worker 			break;
1146*2d543d20SAndroid Build Coastguard Worker 		case 'f':
1147*2d543d20SAndroid Build Coastguard Worker 			display_bools();
1148*2d543d20SAndroid Build Coastguard Worker 			break;
1149*2d543d20SAndroid Build Coastguard Worker 		case 'g':
1150*2d543d20SAndroid Build Coastguard Worker 			display_cond_expressions();
1151*2d543d20SAndroid Build Coastguard Worker 			break;
1152*2d543d20SAndroid Build Coastguard Worker 		case 'h':
1153*2d543d20SAndroid Build Coastguard Worker 			printf("name? ");
1154*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1155*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1156*2d543d20SAndroid Build Coastguard Worker 
1157*2d543d20SAndroid Build Coastguard Worker 			name = strdup(ans);
1158*2d543d20SAndroid Build Coastguard Worker 			if (name == NULL) {
1159*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "couldn't strdup string.\n");
1160*2d543d20SAndroid Build Coastguard Worker 				break;
1161*2d543d20SAndroid Build Coastguard Worker 			}
1162*2d543d20SAndroid Build Coastguard Worker 
1163*2d543d20SAndroid Build Coastguard Worker 			printf("state? ");
1164*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1165*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1166*2d543d20SAndroid Build Coastguard Worker 
1167*2d543d20SAndroid Build Coastguard Worker 			if (atoi(ans))
1168*2d543d20SAndroid Build Coastguard Worker 				state = 1;
1169*2d543d20SAndroid Build Coastguard Worker 			else
1170*2d543d20SAndroid Build Coastguard Worker 				state = 0;
1171*2d543d20SAndroid Build Coastguard Worker 
1172*2d543d20SAndroid Build Coastguard Worker 			change_bool(name, state);
1173*2d543d20SAndroid Build Coastguard Worker 			free(name);
1174*2d543d20SAndroid Build Coastguard Worker 			break;
1175*2d543d20SAndroid Build Coastguard Worker 		case 'i':
1176*2d543d20SAndroid Build Coastguard Worker 			printf("source sid?  ");
1177*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1178*2d543d20SAndroid Build Coastguard Worker 			ssid = atoi(ans);
1179*2d543d20SAndroid Build Coastguard Worker 
1180*2d543d20SAndroid Build Coastguard Worker 			printf("target sid?  ");
1181*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1182*2d543d20SAndroid Build Coastguard Worker 			tsid = atoi(ans);
1183*2d543d20SAndroid Build Coastguard Worker 
1184*2d543d20SAndroid Build Coastguard Worker 			printf("target class?  ");
1185*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1186*2d543d20SAndroid Build Coastguard Worker 			if (isdigit(ans[0])) {
1187*2d543d20SAndroid Build Coastguard Worker 				tclass = atoi(ans);
1188*2d543d20SAndroid Build Coastguard Worker 				if (!tclass
1189*2d543d20SAndroid Build Coastguard Worker 				    || tclass > policydb.p_classes.nprim) {
1190*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class.\n");
1191*2d543d20SAndroid Build Coastguard Worker 					break;
1192*2d543d20SAndroid Build Coastguard Worker 				}
1193*2d543d20SAndroid Build Coastguard Worker 			} else {
1194*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1195*2d543d20SAndroid Build Coastguard Worker 				cladatum =
1196*2d543d20SAndroid Build Coastguard Worker 				    (class_datum_t *) hashtab_search(policydb.
1197*2d543d20SAndroid Build Coastguard Worker 								     p_classes.
1198*2d543d20SAndroid Build Coastguard Worker 								     table,
1199*2d543d20SAndroid Build Coastguard Worker 								     ans);
1200*2d543d20SAndroid Build Coastguard Worker 				if (!cladatum) {
1201*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class\n");
1202*2d543d20SAndroid Build Coastguard Worker 					break;
1203*2d543d20SAndroid Build Coastguard Worker 				}
1204*2d543d20SAndroid Build Coastguard Worker 				tclass = cladatum->s.value;
1205*2d543d20SAndroid Build Coastguard Worker 			}
1206*2d543d20SAndroid Build Coastguard Worker 
1207*2d543d20SAndroid Build Coastguard Worker 			flags = SHOW_GRANTED;
1208*2d543d20SAndroid Build Coastguard Worker 			if (sepol_compute_av_reason_buffer(ssid, tsid,
1209*2d543d20SAndroid Build Coastguard Worker 					tclass, 0, &avd, &reason,
1210*2d543d20SAndroid Build Coastguard Worker 					&reason_buf, flags)) {
1211*2d543d20SAndroid Build Coastguard Worker 				printf("\nconstraint error\n");
1212*2d543d20SAndroid Build Coastguard Worker 				break;
1213*2d543d20SAndroid Build Coastguard Worker 			}
1214*2d543d20SAndroid Build Coastguard Worker 			if (reason_buf) {
1215*2d543d20SAndroid Build Coastguard Worker 				printf("\nConstraint expressions:\n%s",
1216*2d543d20SAndroid Build Coastguard Worker 						reason_buf);
1217*2d543d20SAndroid Build Coastguard Worker 				free(reason_buf);
1218*2d543d20SAndroid Build Coastguard Worker 			} else {
1219*2d543d20SAndroid Build Coastguard Worker 				printf("\nNo constraints found.\n");
1220*2d543d20SAndroid Build Coastguard Worker 			}
1221*2d543d20SAndroid Build Coastguard Worker 			break;
1222*2d543d20SAndroid Build Coastguard Worker 		case 'j':
1223*2d543d20SAndroid Build Coastguard Worker 			printf("old sid?  ");
1224*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1225*2d543d20SAndroid Build Coastguard Worker 			oldsid = atoi(ans);
1226*2d543d20SAndroid Build Coastguard Worker 
1227*2d543d20SAndroid Build Coastguard Worker 			printf("new sid?  ");
1228*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1229*2d543d20SAndroid Build Coastguard Worker 			newsid = atoi(ans);
1230*2d543d20SAndroid Build Coastguard Worker 
1231*2d543d20SAndroid Build Coastguard Worker 			printf("task sid?  ");
1232*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1233*2d543d20SAndroid Build Coastguard Worker 			tasksid = atoi(ans);
1234*2d543d20SAndroid Build Coastguard Worker 
1235*2d543d20SAndroid Build Coastguard Worker 			printf("target class?  ");
1236*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1237*2d543d20SAndroid Build Coastguard Worker 			if (isdigit(ans[0])) {
1238*2d543d20SAndroid Build Coastguard Worker 				tclass = atoi(ans);
1239*2d543d20SAndroid Build Coastguard Worker 				if (!tclass
1240*2d543d20SAndroid Build Coastguard Worker 				    || tclass > policydb.p_classes.nprim) {
1241*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class.\n");
1242*2d543d20SAndroid Build Coastguard Worker 					break;
1243*2d543d20SAndroid Build Coastguard Worker 				}
1244*2d543d20SAndroid Build Coastguard Worker 			} else {
1245*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1246*2d543d20SAndroid Build Coastguard Worker 				cladatum =
1247*2d543d20SAndroid Build Coastguard Worker 				    (class_datum_t *) hashtab_search(policydb.
1248*2d543d20SAndroid Build Coastguard Worker 								     p_classes.
1249*2d543d20SAndroid Build Coastguard Worker 								     table,
1250*2d543d20SAndroid Build Coastguard Worker 								     ans);
1251*2d543d20SAndroid Build Coastguard Worker 				if (!cladatum) {
1252*2d543d20SAndroid Build Coastguard Worker 					printf("\nNo such class\n");
1253*2d543d20SAndroid Build Coastguard Worker 					break;
1254*2d543d20SAndroid Build Coastguard Worker 				}
1255*2d543d20SAndroid Build Coastguard Worker 				tclass = cladatum->s.value;
1256*2d543d20SAndroid Build Coastguard Worker 			}
1257*2d543d20SAndroid Build Coastguard Worker 
1258*2d543d20SAndroid Build Coastguard Worker 			flags = SHOW_GRANTED;
1259*2d543d20SAndroid Build Coastguard Worker 			if (sepol_validate_transition_reason_buffer(oldsid,
1260*2d543d20SAndroid Build Coastguard Worker 						newsid, tasksid, tclass,
1261*2d543d20SAndroid Build Coastguard Worker 						&reason_buf, flags)) {
1262*2d543d20SAndroid Build Coastguard Worker 				printf("\nvalidatetrans error\n");
1263*2d543d20SAndroid Build Coastguard Worker 				break;
1264*2d543d20SAndroid Build Coastguard Worker 			}
1265*2d543d20SAndroid Build Coastguard Worker 			if (reason_buf) {
1266*2d543d20SAndroid Build Coastguard Worker 				printf("\nValidatetrans expressions:\n%s",
1267*2d543d20SAndroid Build Coastguard Worker 						reason_buf);
1268*2d543d20SAndroid Build Coastguard Worker 				free(reason_buf);
1269*2d543d20SAndroid Build Coastguard Worker 			} else {
1270*2d543d20SAndroid Build Coastguard Worker 				printf(
1271*2d543d20SAndroid Build Coastguard Worker 				    "\nNo validatetrans expressions found.\n");
1272*2d543d20SAndroid Build Coastguard Worker 			}
1273*2d543d20SAndroid Build Coastguard Worker 			break;
1274*2d543d20SAndroid Build Coastguard Worker 		case 'k':
1275*2d543d20SAndroid Build Coastguard Worker 			{
1276*2d543d20SAndroid Build Coastguard Worker 				char *p;
1277*2d543d20SAndroid Build Coastguard Worker 				struct in6_addr addr6;
1278*2d543d20SAndroid Build Coastguard Worker 				uint64_t subnet_prefix;
1279*2d543d20SAndroid Build Coastguard Worker 				unsigned int pkey;
1280*2d543d20SAndroid Build Coastguard Worker 
1281*2d543d20SAndroid Build Coastguard Worker 				printf("subnet prefix?  ");
1282*2d543d20SAndroid Build Coastguard Worker 				FGETS(ans, sizeof(ans), stdin);
1283*2d543d20SAndroid Build Coastguard Worker 				ans[strlen(ans) - 1] = 0;
1284*2d543d20SAndroid Build Coastguard Worker 				p = (char *)&addr6;
1285*2d543d20SAndroid Build Coastguard Worker 
1286*2d543d20SAndroid Build Coastguard Worker 				if (inet_pton(AF_INET6, ans, p) < 1) {
1287*2d543d20SAndroid Build Coastguard Worker 					printf("error parsing subnet prefix\n");
1288*2d543d20SAndroid Build Coastguard Worker 					break;
1289*2d543d20SAndroid Build Coastguard Worker 				}
1290*2d543d20SAndroid Build Coastguard Worker 
1291*2d543d20SAndroid Build Coastguard Worker 				memcpy(&subnet_prefix, p, sizeof(subnet_prefix));
1292*2d543d20SAndroid Build Coastguard Worker 				printf("pkey? ");
1293*2d543d20SAndroid Build Coastguard Worker 				FGETS(ans, sizeof(ans), stdin);
1294*2d543d20SAndroid Build Coastguard Worker 				pkey = atoi(ans);
1295*2d543d20SAndroid Build Coastguard Worker 				sepol_ibpkey_sid(subnet_prefix, pkey, &ssid);
1296*2d543d20SAndroid Build Coastguard Worker 				printf("sid %d\n", ssid);
1297*2d543d20SAndroid Build Coastguard Worker 			}
1298*2d543d20SAndroid Build Coastguard Worker 			break;
1299*2d543d20SAndroid Build Coastguard Worker 		case 'l':
1300*2d543d20SAndroid Build Coastguard Worker 			printf("device name (eg. mlx4_0)?  ");
1301*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1302*2d543d20SAndroid Build Coastguard Worker 			ans[strlen(ans) - 1] = 0;
1303*2d543d20SAndroid Build Coastguard Worker 
1304*2d543d20SAndroid Build Coastguard Worker 			name = strdup(ans);
1305*2d543d20SAndroid Build Coastguard Worker 			if (!name) {
1306*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "couldn't strdup string.\n");
1307*2d543d20SAndroid Build Coastguard Worker 				break;
1308*2d543d20SAndroid Build Coastguard Worker 			}
1309*2d543d20SAndroid Build Coastguard Worker 
1310*2d543d20SAndroid Build Coastguard Worker 			printf("port? ");
1311*2d543d20SAndroid Build Coastguard Worker 			FGETS(ans, sizeof(ans), stdin);
1312*2d543d20SAndroid Build Coastguard Worker 			port = atoi(ans);
1313*2d543d20SAndroid Build Coastguard Worker 			sepol_ibendport_sid(name, port, &ssid);
1314*2d543d20SAndroid Build Coastguard Worker 			printf("sid %d\n", ssid);
1315*2d543d20SAndroid Build Coastguard Worker 			free(name);
1316*2d543d20SAndroid Build Coastguard Worker 			break;
1317*2d543d20SAndroid Build Coastguard Worker #ifdef EQUIVTYPES
1318*2d543d20SAndroid Build Coastguard Worker 		case 'z':
1319*2d543d20SAndroid Build Coastguard Worker 			identify_equiv_types();
1320*2d543d20SAndroid Build Coastguard Worker 			break;
1321*2d543d20SAndroid Build Coastguard Worker #endif
1322*2d543d20SAndroid Build Coastguard Worker 		case 'm':
1323*2d543d20SAndroid Build Coastguard Worker 			goto menu;
1324*2d543d20SAndroid Build Coastguard Worker 		case 'q':
1325*2d543d20SAndroid Build Coastguard Worker 			exit(0);
1326*2d543d20SAndroid Build Coastguard Worker 			break;
1327*2d543d20SAndroid Build Coastguard Worker 		default:
1328*2d543d20SAndroid Build Coastguard Worker 			printf("\nUnknown option %s.\n", ans);
1329*2d543d20SAndroid Build Coastguard Worker 		}
1330*2d543d20SAndroid Build Coastguard Worker 	}
1331*2d543d20SAndroid Build Coastguard Worker 
1332*2d543d20SAndroid Build Coastguard Worker 	return 0;
1333*2d543d20SAndroid Build Coastguard Worker }
1334*2d543d20SAndroid Build Coastguard Worker 
1335*2d543d20SAndroid Build Coastguard Worker /* FLASK */
1336