16cd6a6acSopenharmony_ci
26cd6a6acSopenharmony_ci/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
36cd6a6acSopenharmony_ci *
46cd6a6acSopenharmony_ci * Copyright (C) 2003 Tresys Technology, LLC
56cd6a6acSopenharmony_ci *	This program is free software; you can redistribute it and/or modify
66cd6a6acSopenharmony_ci *  	it under the terms of the GNU General Public License as published by
76cd6a6acSopenharmony_ci *	the Free Software Foundation, version 2.
86cd6a6acSopenharmony_ci */
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ci/*
116cd6a6acSopenharmony_ci * displaypol.c
126cd6a6acSopenharmony_ci *
136cd6a6acSopenharmony_ci * Test program to the contents of a binary policy in text
146cd6a6acSopenharmony_ci * form.  This program currently only displays the
156cd6a6acSopenharmony_ci * avtab (including conditional avtab) rules.
166cd6a6acSopenharmony_ci *
176cd6a6acSopenharmony_ci * 	displaypol binary_pol_file
186cd6a6acSopenharmony_ci */
196cd6a6acSopenharmony_ci
206cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h>
216cd6a6acSopenharmony_ci#include <sepol/policydb/avtab.h>
226cd6a6acSopenharmony_ci#include <sepol/policydb/services.h>
236cd6a6acSopenharmony_ci#include <sepol/policydb/conditional.h>
246cd6a6acSopenharmony_ci#include <sepol/policydb/util.h>
256cd6a6acSopenharmony_ci#include <sepol/policydb/polcaps.h>
266cd6a6acSopenharmony_ci#include <getopt.h>
276cd6a6acSopenharmony_ci#include <assert.h>
286cd6a6acSopenharmony_ci#include <unistd.h>
296cd6a6acSopenharmony_ci#include <stdlib.h>
306cd6a6acSopenharmony_ci#include <sys/stat.h>
316cd6a6acSopenharmony_ci#include <sys/types.h>
326cd6a6acSopenharmony_ci#include <sys/mman.h>
336cd6a6acSopenharmony_ci#include <errno.h>
346cd6a6acSopenharmony_ci#include <stdio.h>
356cd6a6acSopenharmony_ci#include <fcntl.h>
366cd6a6acSopenharmony_ci
376cd6a6acSopenharmony_cistatic policydb_t policydb;
386cd6a6acSopenharmony_ci
396cd6a6acSopenharmony_cistatic __attribute__((__noreturn__)) void usage(const char *progname)
406cd6a6acSopenharmony_ci{
416cd6a6acSopenharmony_ci	printf("usage:  %s binary_pol_file\n\n", progname);
426cd6a6acSopenharmony_ci	exit(1);
436cd6a6acSopenharmony_ci}
446cd6a6acSopenharmony_ci
456cd6a6acSopenharmony_cistatic int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
466cd6a6acSopenharmony_ci		       FILE * fp)
476cd6a6acSopenharmony_ci{
486cd6a6acSopenharmony_ci	char *perm;
496cd6a6acSopenharmony_ci	fprintf(fp, "{");
506cd6a6acSopenharmony_ci	perm = sepol_av_to_string(p, key->target_class, mask);
516cd6a6acSopenharmony_ci	if (perm)
526cd6a6acSopenharmony_ci		fprintf(fp, "%s ", perm);
536cd6a6acSopenharmony_ci	fprintf(fp, "}");
546cd6a6acSopenharmony_ci	return 0;
556cd6a6acSopenharmony_ci}
566cd6a6acSopenharmony_ci
576cd6a6acSopenharmony_cistatic int render_type(uint32_t type, policydb_t * p, FILE * fp)
586cd6a6acSopenharmony_ci{
596cd6a6acSopenharmony_ci	fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
606cd6a6acSopenharmony_ci	return 0;
616cd6a6acSopenharmony_ci}
626cd6a6acSopenharmony_ci
636cd6a6acSopenharmony_cistatic int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
646cd6a6acSopenharmony_ci{
656cd6a6acSopenharmony_ci	char *stype, *ttype, *tclass;
666cd6a6acSopenharmony_ci	stype = p->p_type_val_to_name[key->source_type - 1];
676cd6a6acSopenharmony_ci	ttype = p->p_type_val_to_name[key->target_type - 1];
686cd6a6acSopenharmony_ci	tclass = p->p_class_val_to_name[key->target_class - 1];
696cd6a6acSopenharmony_ci	if (stype && ttype)
706cd6a6acSopenharmony_ci		fprintf(fp, "%s %s : %s ", stype, ttype, tclass);
716cd6a6acSopenharmony_ci	else if (stype)
726cd6a6acSopenharmony_ci		fprintf(fp, "%s %u : %s ", stype, key->target_type, tclass);
736cd6a6acSopenharmony_ci	else if (ttype)
746cd6a6acSopenharmony_ci		fprintf(fp, "%u %s : %s ", key->source_type, ttype, tclass);
756cd6a6acSopenharmony_ci	else
766cd6a6acSopenharmony_ci		fprintf(fp, "%u %u : %s ", key->source_type, key->target_type,
776cd6a6acSopenharmony_ci			tclass);
786cd6a6acSopenharmony_ci	return 0;
796cd6a6acSopenharmony_ci}
806cd6a6acSopenharmony_ci
816cd6a6acSopenharmony_ci/* 'what' values for this function */
826cd6a6acSopenharmony_ci#define	RENDER_UNCONDITIONAL	0x0001	/* render all regardless of enabled state */
836cd6a6acSopenharmony_ci#define RENDER_ENABLED		0x0002
846cd6a6acSopenharmony_ci#define RENDER_DISABLED		0x0004
856cd6a6acSopenharmony_ci#define RENDER_CONDITIONAL	(RENDER_ENABLED|RENDER_DISABLED)
866cd6a6acSopenharmony_ci
876cd6a6acSopenharmony_cistatic int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
886cd6a6acSopenharmony_ci		   policydb_t * p, FILE * fp)
896cd6a6acSopenharmony_ci{
906cd6a6acSopenharmony_ci	if (!(what & RENDER_UNCONDITIONAL)) {
916cd6a6acSopenharmony_ci		if (what != RENDER_CONDITIONAL && (((what & RENDER_ENABLED)
926cd6a6acSopenharmony_ci						    && !(key->
936cd6a6acSopenharmony_ci							 specified &
946cd6a6acSopenharmony_ci							 AVTAB_ENABLED))
956cd6a6acSopenharmony_ci						   || ((what & RENDER_DISABLED)
966cd6a6acSopenharmony_ci						       && (key->
976cd6a6acSopenharmony_ci							   specified &
986cd6a6acSopenharmony_ci							   AVTAB_ENABLED)))) {
996cd6a6acSopenharmony_ci			return 0;	/* doesn't match selection criteria */
1006cd6a6acSopenharmony_ci		}
1016cd6a6acSopenharmony_ci	}
1026cd6a6acSopenharmony_ci
1036cd6a6acSopenharmony_ci	if (!(what & RENDER_UNCONDITIONAL)) {
1046cd6a6acSopenharmony_ci		if (key->specified & AVTAB_ENABLED)
1056cd6a6acSopenharmony_ci			fprintf(fp, "[enabled] ");
1066cd6a6acSopenharmony_ci		else if (!(key->specified & AVTAB_ENABLED))
1076cd6a6acSopenharmony_ci			fprintf(fp, "[disabled] ");
1086cd6a6acSopenharmony_ci	}
1096cd6a6acSopenharmony_ci
1106cd6a6acSopenharmony_ci	if (key->specified & AVTAB_AV) {
1116cd6a6acSopenharmony_ci		if (key->specified & AVTAB_ALLOWED) {
1126cd6a6acSopenharmony_ci			fprintf(fp, "allow ");
1136cd6a6acSopenharmony_ci			render_key(key, p, fp);
1146cd6a6acSopenharmony_ci			render_access_mask(datum->data, key, p, fp);
1156cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1166cd6a6acSopenharmony_ci		}
1176cd6a6acSopenharmony_ci		if (key->specified & AVTAB_AUDITALLOW) {
1186cd6a6acSopenharmony_ci			fprintf(fp, "auditallow ");
1196cd6a6acSopenharmony_ci			render_key(key, p, fp);
1206cd6a6acSopenharmony_ci			render_access_mask(datum->data, key, p, fp);
1216cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1226cd6a6acSopenharmony_ci		}
1236cd6a6acSopenharmony_ci		if (key->specified & AVTAB_AUDITDENY) {
1246cd6a6acSopenharmony_ci			fprintf(fp, "dontaudit ");
1256cd6a6acSopenharmony_ci			render_key(key, p, fp);
1266cd6a6acSopenharmony_ci			/* We inverse the mask for dontaudit since the mask is internally stored
1276cd6a6acSopenharmony_ci			 * as a auditdeny mask */
1286cd6a6acSopenharmony_ci			render_access_mask(~datum->data, key, p, fp);
1296cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1306cd6a6acSopenharmony_ci		}
1316cd6a6acSopenharmony_ci	} else if (key->specified & AVTAB_TYPE) {
1326cd6a6acSopenharmony_ci		if (key->specified & AVTAB_TRANSITION) {
1336cd6a6acSopenharmony_ci			fprintf(fp, "type_transition ");
1346cd6a6acSopenharmony_ci			render_key(key, p, fp);
1356cd6a6acSopenharmony_ci			render_type(datum->data, p, fp);
1366cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1376cd6a6acSopenharmony_ci		}
1386cd6a6acSopenharmony_ci		if (key->specified & AVTAB_MEMBER) {
1396cd6a6acSopenharmony_ci			fprintf(fp, "type_member ");
1406cd6a6acSopenharmony_ci			render_key(key, p, fp);
1416cd6a6acSopenharmony_ci			render_type(datum->data, p, fp);
1426cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1436cd6a6acSopenharmony_ci		}
1446cd6a6acSopenharmony_ci		if (key->specified & AVTAB_CHANGE) {
1456cd6a6acSopenharmony_ci			fprintf(fp, "type_change ");
1466cd6a6acSopenharmony_ci			render_key(key, p, fp);
1476cd6a6acSopenharmony_ci			render_type(datum->data, p, fp);
1486cd6a6acSopenharmony_ci			fprintf(fp, ";\n");
1496cd6a6acSopenharmony_ci		}
1506cd6a6acSopenharmony_ci	} else if (key->specified & AVTAB_XPERMS) {
1516cd6a6acSopenharmony_ci		if (key->specified & AVTAB_XPERMS_ALLOWED)
1526cd6a6acSopenharmony_ci			fprintf(fp, "allowxperm ");
1536cd6a6acSopenharmony_ci		else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
1546cd6a6acSopenharmony_ci			fprintf(fp, "auditallowxperm ");
1556cd6a6acSopenharmony_ci		else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
1566cd6a6acSopenharmony_ci			fprintf(fp, "dontauditxperm ");
1576cd6a6acSopenharmony_ci		render_key(key, p, fp);
1586cd6a6acSopenharmony_ci		fprintf(fp, "%s;\n", sepol_extended_perms_to_string(datum->xperms));
1596cd6a6acSopenharmony_ci	} else {
1606cd6a6acSopenharmony_ci		fprintf(fp, "     ERROR: no valid rule type specified\n");
1616cd6a6acSopenharmony_ci		return -1;
1626cd6a6acSopenharmony_ci	}
1636cd6a6acSopenharmony_ci	return 0;
1646cd6a6acSopenharmony_ci}
1656cd6a6acSopenharmony_ci
1666cd6a6acSopenharmony_cistatic int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
1676cd6a6acSopenharmony_ci{
1686cd6a6acSopenharmony_ci	unsigned int i;
1696cd6a6acSopenharmony_ci	avtab_ptr_t cur;
1706cd6a6acSopenharmony_ci
1716cd6a6acSopenharmony_ci	/* hmm...should have used avtab_map. */
1726cd6a6acSopenharmony_ci	for (i = 0; i < a->nslot; i++) {
1736cd6a6acSopenharmony_ci		for (cur = a->htable[i]; cur; cur = cur->next) {
1746cd6a6acSopenharmony_ci			render_av_rule(&cur->key, &cur->datum, what, p, fp);
1756cd6a6acSopenharmony_ci		}
1766cd6a6acSopenharmony_ci	}
1776cd6a6acSopenharmony_ci	fprintf(fp, "\n");
1786cd6a6acSopenharmony_ci	return 0;
1796cd6a6acSopenharmony_ci}
1806cd6a6acSopenharmony_ci
1816cd6a6acSopenharmony_cistatic int display_bools(policydb_t * p, FILE * fp)
1826cd6a6acSopenharmony_ci{
1836cd6a6acSopenharmony_ci	unsigned int i;
1846cd6a6acSopenharmony_ci
1856cd6a6acSopenharmony_ci	for (i = 0; i < p->p_bools.nprim; i++) {
1866cd6a6acSopenharmony_ci		fprintf(fp, "%s : %d\n", p->p_bool_val_to_name[i],
1876cd6a6acSopenharmony_ci			p->bool_val_to_struct[i]->state);
1886cd6a6acSopenharmony_ci	}
1896cd6a6acSopenharmony_ci	return 0;
1906cd6a6acSopenharmony_ci}
1916cd6a6acSopenharmony_ci
1926cd6a6acSopenharmony_cistatic void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
1936cd6a6acSopenharmony_ci{
1946cd6a6acSopenharmony_ci
1956cd6a6acSopenharmony_ci	cond_expr_t *cur;
1966cd6a6acSopenharmony_ci	for (cur = exp; cur != NULL; cur = cur->next) {
1976cd6a6acSopenharmony_ci		switch (cur->expr_type) {
1986cd6a6acSopenharmony_ci		case COND_BOOL:
1996cd6a6acSopenharmony_ci			fprintf(fp, "%s ",
2006cd6a6acSopenharmony_ci				p->p_bool_val_to_name[cur->bool - 1]);
2016cd6a6acSopenharmony_ci			break;
2026cd6a6acSopenharmony_ci		case COND_NOT:
2036cd6a6acSopenharmony_ci			fprintf(fp, "! ");
2046cd6a6acSopenharmony_ci			break;
2056cd6a6acSopenharmony_ci		case COND_OR:
2066cd6a6acSopenharmony_ci			fprintf(fp, "|| ");
2076cd6a6acSopenharmony_ci			break;
2086cd6a6acSopenharmony_ci		case COND_AND:
2096cd6a6acSopenharmony_ci			fprintf(fp, "&& ");
2106cd6a6acSopenharmony_ci			break;
2116cd6a6acSopenharmony_ci		case COND_XOR:
2126cd6a6acSopenharmony_ci			fprintf(fp, "^ ");
2136cd6a6acSopenharmony_ci			break;
2146cd6a6acSopenharmony_ci		case COND_EQ:
2156cd6a6acSopenharmony_ci			fprintf(fp, "== ");
2166cd6a6acSopenharmony_ci			break;
2176cd6a6acSopenharmony_ci		case COND_NEQ:
2186cd6a6acSopenharmony_ci			fprintf(fp, "!= ");
2196cd6a6acSopenharmony_ci			break;
2206cd6a6acSopenharmony_ci		default:
2216cd6a6acSopenharmony_ci			fprintf(fp, "error!");
2226cd6a6acSopenharmony_ci			break;
2236cd6a6acSopenharmony_ci		}
2246cd6a6acSopenharmony_ci	}
2256cd6a6acSopenharmony_ci}
2266cd6a6acSopenharmony_ci
2276cd6a6acSopenharmony_cistatic int display_cond_expressions(policydb_t * p, FILE * fp)
2286cd6a6acSopenharmony_ci{
2296cd6a6acSopenharmony_ci	cond_node_t *cur;
2306cd6a6acSopenharmony_ci	cond_av_list_t *av_cur;
2316cd6a6acSopenharmony_ci
2326cd6a6acSopenharmony_ci	for (cur = p->cond_list; cur != NULL; cur = cur->next) {
2336cd6a6acSopenharmony_ci		fprintf(fp, "expression: ");
2346cd6a6acSopenharmony_ci		display_expr(p, cur->expr, fp);
2356cd6a6acSopenharmony_ci		fprintf(fp, "current state: %d\n", cur->cur_state);
2366cd6a6acSopenharmony_ci		fprintf(fp, "True list:\n");
2376cd6a6acSopenharmony_ci		for (av_cur = cur->true_list; av_cur != NULL; av_cur = av_cur->next) {
2386cd6a6acSopenharmony_ci			fprintf(fp, "\t");
2396cd6a6acSopenharmony_ci			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
2406cd6a6acSopenharmony_ci				       RENDER_CONDITIONAL, p, fp);
2416cd6a6acSopenharmony_ci		}
2426cd6a6acSopenharmony_ci		fprintf(fp, "False list:\n");
2436cd6a6acSopenharmony_ci		for (av_cur = cur->false_list; av_cur != NULL; av_cur = av_cur->next) {
2446cd6a6acSopenharmony_ci			fprintf(fp, "\t");
2456cd6a6acSopenharmony_ci			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
2466cd6a6acSopenharmony_ci				       RENDER_CONDITIONAL, p, fp);
2476cd6a6acSopenharmony_ci		}
2486cd6a6acSopenharmony_ci	}
2496cd6a6acSopenharmony_ci	return 0;
2506cd6a6acSopenharmony_ci}
2516cd6a6acSopenharmony_ci
2526cd6a6acSopenharmony_cistatic int display_handle_unknown(policydb_t * p, FILE * out_fp)
2536cd6a6acSopenharmony_ci{
2546cd6a6acSopenharmony_ci	if (p->handle_unknown == ALLOW_UNKNOWN)
2556cd6a6acSopenharmony_ci		fprintf(out_fp, "Allow unknown classes and permissions\n");
2566cd6a6acSopenharmony_ci	else if (p->handle_unknown == DENY_UNKNOWN)
2576cd6a6acSopenharmony_ci		fprintf(out_fp, "Deny unknown classes and permissions\n");
2586cd6a6acSopenharmony_ci	else if (p->handle_unknown == REJECT_UNKNOWN)
2596cd6a6acSopenharmony_ci		fprintf(out_fp, "Reject unknown classes and permissions\n");
2606cd6a6acSopenharmony_ci	return 0;
2616cd6a6acSopenharmony_ci}
2626cd6a6acSopenharmony_ci
2636cd6a6acSopenharmony_cistatic int change_bool(char *name, int state, policydb_t * p, FILE * fp)
2646cd6a6acSopenharmony_ci{
2656cd6a6acSopenharmony_ci	cond_bool_datum_t *bool;
2666cd6a6acSopenharmony_ci
2676cd6a6acSopenharmony_ci	bool = hashtab_search(p->p_bools.table, name);
2686cd6a6acSopenharmony_ci	if (bool == NULL) {
2696cd6a6acSopenharmony_ci		fprintf(fp, "Could not find bool %s\n", name);
2706cd6a6acSopenharmony_ci		return -1;
2716cd6a6acSopenharmony_ci	}
2726cd6a6acSopenharmony_ci	bool->state = state;
2736cd6a6acSopenharmony_ci	evaluate_conds(p);
2746cd6a6acSopenharmony_ci	return 0;
2756cd6a6acSopenharmony_ci}
2766cd6a6acSopenharmony_ci
2776cd6a6acSopenharmony_cistatic void display_policycaps(policydb_t * p, FILE * fp)
2786cd6a6acSopenharmony_ci{
2796cd6a6acSopenharmony_ci	ebitmap_node_t *node;
2806cd6a6acSopenharmony_ci	const char *capname;
2816cd6a6acSopenharmony_ci	char buf[64];
2826cd6a6acSopenharmony_ci	unsigned int i;
2836cd6a6acSopenharmony_ci
2846cd6a6acSopenharmony_ci	fprintf(fp, "policy capabilities:\n");
2856cd6a6acSopenharmony_ci	ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
2866cd6a6acSopenharmony_ci		capname = sepol_polcap_getname(i);
2876cd6a6acSopenharmony_ci		if (capname == NULL) {
2886cd6a6acSopenharmony_ci			snprintf(buf, sizeof(buf), "unknown (%u)", i);
2896cd6a6acSopenharmony_ci			capname = buf;
2906cd6a6acSopenharmony_ci		}
2916cd6a6acSopenharmony_ci		fprintf(fp, "\t%s\n", capname);
2926cd6a6acSopenharmony_ci	}
2936cd6a6acSopenharmony_ci}
2946cd6a6acSopenharmony_ci
2956cd6a6acSopenharmony_cistatic void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
2966cd6a6acSopenharmony_ci		       uint32_t symbol_value, const char *prefix)
2976cd6a6acSopenharmony_ci{
2986cd6a6acSopenharmony_ci	const char *id = p->sym_val_to_name[symbol_type][symbol_value];
2996cd6a6acSopenharmony_ci	fprintf(fp, " %s%s", prefix, id);
3006cd6a6acSopenharmony_ci}
3016cd6a6acSopenharmony_ci
3026cd6a6acSopenharmony_cistatic void display_permissive(policydb_t *p, FILE *fp)
3036cd6a6acSopenharmony_ci{
3046cd6a6acSopenharmony_ci	ebitmap_node_t *node;
3056cd6a6acSopenharmony_ci	unsigned int i;
3066cd6a6acSopenharmony_ci
3076cd6a6acSopenharmony_ci	fprintf(fp, "permissive sids:\n");
3086cd6a6acSopenharmony_ci	ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
3096cd6a6acSopenharmony_ci		fprintf(fp, "\t");
3106cd6a6acSopenharmony_ci		display_id(p, fp, SYM_TYPES, i - 1, "");
3116cd6a6acSopenharmony_ci		fprintf(fp, "\n");
3126cd6a6acSopenharmony_ci	}
3136cd6a6acSopenharmony_ci}
3146cd6a6acSopenharmony_ci
3156cd6a6acSopenharmony_cistatic void display_role_trans(policydb_t *p, FILE *fp)
3166cd6a6acSopenharmony_ci{
3176cd6a6acSopenharmony_ci	role_trans_t *rt;
3186cd6a6acSopenharmony_ci
3196cd6a6acSopenharmony_ci	fprintf(fp, "role_trans rules:\n");
3206cd6a6acSopenharmony_ci	for (rt = p->role_tr; rt; rt = rt->next) {
3216cd6a6acSopenharmony_ci		display_id(p, fp, SYM_ROLES, rt->role - 1, "");
3226cd6a6acSopenharmony_ci		display_id(p, fp, SYM_TYPES, rt->type - 1, "");
3236cd6a6acSopenharmony_ci		display_id(p, fp, SYM_CLASSES, rt->tclass - 1, ":");
3246cd6a6acSopenharmony_ci		display_id(p, fp, SYM_ROLES, rt->new_role - 1, "");
3256cd6a6acSopenharmony_ci		fprintf(fp, "\n");
3266cd6a6acSopenharmony_ci	}
3276cd6a6acSopenharmony_ci}
3286cd6a6acSopenharmony_ci
3296cd6a6acSopenharmony_cistruct filenametr_display_args {
3306cd6a6acSopenharmony_ci	policydb_t *p;
3316cd6a6acSopenharmony_ci	FILE *fp;
3326cd6a6acSopenharmony_ci};
3336cd6a6acSopenharmony_ci
3346cd6a6acSopenharmony_cistatic int filenametr_display(hashtab_key_t key,
3356cd6a6acSopenharmony_ci			      hashtab_datum_t datum,
3366cd6a6acSopenharmony_ci			      void *ptr)
3376cd6a6acSopenharmony_ci{
3386cd6a6acSopenharmony_ci	struct filename_trans_key *ft = (struct filename_trans_key *)key;
3396cd6a6acSopenharmony_ci	struct filename_trans_datum *ftdatum = datum;
3406cd6a6acSopenharmony_ci	struct filenametr_display_args *args = ptr;
3416cd6a6acSopenharmony_ci	policydb_t *p = args->p;
3426cd6a6acSopenharmony_ci	FILE *fp = args->fp;
3436cd6a6acSopenharmony_ci	ebitmap_node_t *node;
3446cd6a6acSopenharmony_ci	uint32_t bit;
3456cd6a6acSopenharmony_ci
3466cd6a6acSopenharmony_ci	do {
3476cd6a6acSopenharmony_ci		ebitmap_for_each_positive_bit(&ftdatum->stypes, node, bit) {
3486cd6a6acSopenharmony_ci			display_id(p, fp, SYM_TYPES, bit, "");
3496cd6a6acSopenharmony_ci			display_id(p, fp, SYM_TYPES, ft->ttype - 1, "");
3506cd6a6acSopenharmony_ci			display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":");
3516cd6a6acSopenharmony_ci			display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, "");
3526cd6a6acSopenharmony_ci			fprintf(fp, " %s\n", ft->name);
3536cd6a6acSopenharmony_ci		}
3546cd6a6acSopenharmony_ci		ftdatum = ftdatum->next;
3556cd6a6acSopenharmony_ci	} while (ftdatum);
3566cd6a6acSopenharmony_ci
3576cd6a6acSopenharmony_ci	return 0;
3586cd6a6acSopenharmony_ci}
3596cd6a6acSopenharmony_ci
3606cd6a6acSopenharmony_ci
3616cd6a6acSopenharmony_cistatic void display_filename_trans(policydb_t *p, FILE *fp)
3626cd6a6acSopenharmony_ci{
3636cd6a6acSopenharmony_ci	struct filenametr_display_args args;
3646cd6a6acSopenharmony_ci
3656cd6a6acSopenharmony_ci	fprintf(fp, "filename_trans rules:\n");
3666cd6a6acSopenharmony_ci	args.p = p;
3676cd6a6acSopenharmony_ci	args.fp = fp;
3686cd6a6acSopenharmony_ci	hashtab_map(p->filename_trans, filenametr_display, &args);
3696cd6a6acSopenharmony_ci}
3706cd6a6acSopenharmony_ci
3716cd6a6acSopenharmony_cistatic int menu(void)
3726cd6a6acSopenharmony_ci{
3736cd6a6acSopenharmony_ci	printf("\nSelect a command:\n");
3746cd6a6acSopenharmony_ci	printf("1)  display unconditional AVTAB\n");
3756cd6a6acSopenharmony_ci	printf("2)  display conditional AVTAB (entirely)\n");
3766cd6a6acSopenharmony_ci	printf("3)  display conditional AVTAB (only ENABLED rules)\n");
3776cd6a6acSopenharmony_ci	printf("4)  display conditional AVTAB (only DISABLED rules)\n");
3786cd6a6acSopenharmony_ci	printf("5)  display conditional bools\n");
3796cd6a6acSopenharmony_ci	printf("6)  display conditional expressions\n");
3806cd6a6acSopenharmony_ci	printf("7)  change a boolean value\n");
3816cd6a6acSopenharmony_ci	printf("8)  display role transitions\n");
3826cd6a6acSopenharmony_ci	printf("\n");
3836cd6a6acSopenharmony_ci	printf("c)  display policy capabilities\n");
3846cd6a6acSopenharmony_ci	printf("p)  display the list of permissive types\n");
3856cd6a6acSopenharmony_ci	printf("u)  display unknown handling setting\n");
3866cd6a6acSopenharmony_ci	printf("F)  display filename_trans rules\n");
3876cd6a6acSopenharmony_ci	printf("\n");
3886cd6a6acSopenharmony_ci	printf("f)  set output file\n");
3896cd6a6acSopenharmony_ci	printf("m)  display menu\n");
3906cd6a6acSopenharmony_ci	printf("q)  quit\n");
3916cd6a6acSopenharmony_ci	return 0;
3926cd6a6acSopenharmony_ci}
3936cd6a6acSopenharmony_ci
3946cd6a6acSopenharmony_ciint main(int argc, char **argv)
3956cd6a6acSopenharmony_ci{
3966cd6a6acSopenharmony_ci	FILE *out_fp = stdout;
3976cd6a6acSopenharmony_ci	char ans[81], OutfileName[121];
3986cd6a6acSopenharmony_ci	int fd, ret;
3996cd6a6acSopenharmony_ci	struct stat sb;
4006cd6a6acSopenharmony_ci	void *map;
4016cd6a6acSopenharmony_ci	char *name;
4026cd6a6acSopenharmony_ci	int state;
4036cd6a6acSopenharmony_ci	struct policy_file pf;
4046cd6a6acSopenharmony_ci
4056cd6a6acSopenharmony_ci	if (argc != 2)
4066cd6a6acSopenharmony_ci		usage(argv[0]);
4076cd6a6acSopenharmony_ci
4086cd6a6acSopenharmony_ci	fd = open(argv[1], O_RDONLY);
4096cd6a6acSopenharmony_ci	if (fd < 0) {
4106cd6a6acSopenharmony_ci		fprintf(stderr, "Can't open '%s':  %s\n",
4116cd6a6acSopenharmony_ci			argv[1], strerror(errno));
4126cd6a6acSopenharmony_ci		exit(1);
4136cd6a6acSopenharmony_ci	}
4146cd6a6acSopenharmony_ci	if (fstat(fd, &sb) < 0) {
4156cd6a6acSopenharmony_ci		fprintf(stderr, "Can't stat '%s':  %s\n",
4166cd6a6acSopenharmony_ci			argv[1], strerror(errno));
4176cd6a6acSopenharmony_ci		exit(1);
4186cd6a6acSopenharmony_ci	}
4196cd6a6acSopenharmony_ci	map =
4206cd6a6acSopenharmony_ci	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
4216cd6a6acSopenharmony_ci	if (map == MAP_FAILED) {
4226cd6a6acSopenharmony_ci		fprintf(stderr, "Can't map '%s':  %s\n",
4236cd6a6acSopenharmony_ci			argv[1], strerror(errno));
4246cd6a6acSopenharmony_ci		exit(1);
4256cd6a6acSopenharmony_ci	}
4266cd6a6acSopenharmony_ci
4276cd6a6acSopenharmony_ci	/* read the binary policy */
4286cd6a6acSopenharmony_ci	fprintf(out_fp, "Reading policy...\n");
4296cd6a6acSopenharmony_ci	policy_file_init(&pf);
4306cd6a6acSopenharmony_ci	pf.type = PF_USE_MEMORY;
4316cd6a6acSopenharmony_ci	pf.data = map;
4326cd6a6acSopenharmony_ci	pf.len = sb.st_size;
4336cd6a6acSopenharmony_ci	if (policydb_init(&policydb)) {
4346cd6a6acSopenharmony_ci		fprintf(stderr, "%s:  Out of memory!\n", argv[0]);
4356cd6a6acSopenharmony_ci		exit(1);
4366cd6a6acSopenharmony_ci	}
4376cd6a6acSopenharmony_ci	ret = policydb_read(&policydb, &pf, 1);
4386cd6a6acSopenharmony_ci	if (ret) {
4396cd6a6acSopenharmony_ci		fprintf(stderr,
4406cd6a6acSopenharmony_ci			"%s:  error(s) encountered while parsing configuration\n",
4416cd6a6acSopenharmony_ci			argv[0]);
4426cd6a6acSopenharmony_ci		exit(1);
4436cd6a6acSopenharmony_ci	}
4446cd6a6acSopenharmony_ci
4456cd6a6acSopenharmony_ci	fprintf(stdout, "binary policy file loaded\n\n");
4466cd6a6acSopenharmony_ci	close(fd);
4476cd6a6acSopenharmony_ci
4486cd6a6acSopenharmony_ci	menu();
4496cd6a6acSopenharmony_ci	for (;;) {
4506cd6a6acSopenharmony_ci		printf("\nCommand (\'m\' for menu):  ");
4516cd6a6acSopenharmony_ci		if (fgets(ans, sizeof(ans), stdin) == NULL) {
4526cd6a6acSopenharmony_ci			fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
4536cd6a6acSopenharmony_ci					strerror(errno));
4546cd6a6acSopenharmony_ci			continue;
4556cd6a6acSopenharmony_ci		}
4566cd6a6acSopenharmony_ci		switch (ans[0]) {
4576cd6a6acSopenharmony_ci
4586cd6a6acSopenharmony_ci		case '1':
4596cd6a6acSopenharmony_ci			display_avtab(&policydb.te_avtab, RENDER_UNCONDITIONAL,
4606cd6a6acSopenharmony_ci				      &policydb, out_fp);
4616cd6a6acSopenharmony_ci			break;
4626cd6a6acSopenharmony_ci		case '2':
4636cd6a6acSopenharmony_ci			display_avtab(&policydb.te_cond_avtab,
4646cd6a6acSopenharmony_ci				      RENDER_CONDITIONAL, &policydb, out_fp);
4656cd6a6acSopenharmony_ci			break;
4666cd6a6acSopenharmony_ci		case '3':
4676cd6a6acSopenharmony_ci			display_avtab(&policydb.te_cond_avtab, RENDER_ENABLED,
4686cd6a6acSopenharmony_ci				      &policydb, out_fp);
4696cd6a6acSopenharmony_ci			break;
4706cd6a6acSopenharmony_ci		case '4':
4716cd6a6acSopenharmony_ci			display_avtab(&policydb.te_cond_avtab, RENDER_DISABLED,
4726cd6a6acSopenharmony_ci				      &policydb, out_fp);
4736cd6a6acSopenharmony_ci			break;
4746cd6a6acSopenharmony_ci		case '5':
4756cd6a6acSopenharmony_ci			display_bools(&policydb, out_fp);
4766cd6a6acSopenharmony_ci			break;
4776cd6a6acSopenharmony_ci		case '6':
4786cd6a6acSopenharmony_ci			display_cond_expressions(&policydb, out_fp);
4796cd6a6acSopenharmony_ci			break;
4806cd6a6acSopenharmony_ci		case '7':
4816cd6a6acSopenharmony_ci			printf("name? ");
4826cd6a6acSopenharmony_ci			if (fgets(ans, sizeof(ans), stdin) == NULL) {
4836cd6a6acSopenharmony_ci				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
4846cd6a6acSopenharmony_ci						strerror(errno));
4856cd6a6acSopenharmony_ci				break;
4866cd6a6acSopenharmony_ci			}
4876cd6a6acSopenharmony_ci			ans[strlen(ans) - 1] = 0;
4886cd6a6acSopenharmony_ci
4896cd6a6acSopenharmony_ci			name = strdup(ans);
4906cd6a6acSopenharmony_ci			if (name == NULL) {
4916cd6a6acSopenharmony_ci				fprintf(stderr, "couldn't strdup string.\n");
4926cd6a6acSopenharmony_ci				break;
4936cd6a6acSopenharmony_ci			}
4946cd6a6acSopenharmony_ci
4956cd6a6acSopenharmony_ci			printf("state? ");
4966cd6a6acSopenharmony_ci			if (fgets(ans, sizeof(ans), stdin) == NULL) {
4976cd6a6acSopenharmony_ci				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
4986cd6a6acSopenharmony_ci						strerror(errno));
4996cd6a6acSopenharmony_ci				break;
5006cd6a6acSopenharmony_ci			}
5016cd6a6acSopenharmony_ci			ans[strlen(ans) - 1] = 0;
5026cd6a6acSopenharmony_ci
5036cd6a6acSopenharmony_ci			if (atoi(ans))
5046cd6a6acSopenharmony_ci				state = 1;
5056cd6a6acSopenharmony_ci			else
5066cd6a6acSopenharmony_ci				state = 0;
5076cd6a6acSopenharmony_ci
5086cd6a6acSopenharmony_ci			change_bool(name, state, &policydb, out_fp);
5096cd6a6acSopenharmony_ci			free(name);
5106cd6a6acSopenharmony_ci			break;
5116cd6a6acSopenharmony_ci		case '8':
5126cd6a6acSopenharmony_ci			display_role_trans(&policydb, out_fp);
5136cd6a6acSopenharmony_ci			break;
5146cd6a6acSopenharmony_ci		case 'c':
5156cd6a6acSopenharmony_ci			display_policycaps(&policydb, out_fp);
5166cd6a6acSopenharmony_ci			break;
5176cd6a6acSopenharmony_ci		case 'p':
5186cd6a6acSopenharmony_ci			display_permissive(&policydb, out_fp);
5196cd6a6acSopenharmony_ci			break;
5206cd6a6acSopenharmony_ci		case 'u':
5216cd6a6acSopenharmony_ci		case 'U':
5226cd6a6acSopenharmony_ci			display_handle_unknown(&policydb, out_fp);
5236cd6a6acSopenharmony_ci			break;
5246cd6a6acSopenharmony_ci		case 'f':
5256cd6a6acSopenharmony_ci			printf
5266cd6a6acSopenharmony_ci			    ("\nFilename for output (<CR> for screen output): ");
5276cd6a6acSopenharmony_ci			if (fgets(OutfileName, sizeof(OutfileName), stdin) == NULL) {
5286cd6a6acSopenharmony_ci				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
5296cd6a6acSopenharmony_ci						strerror(errno));
5306cd6a6acSopenharmony_ci				break;
5316cd6a6acSopenharmony_ci			}
5326cd6a6acSopenharmony_ci			OutfileName[strlen(OutfileName) - 1] = '\0';	/* fix_string (remove LF) */
5336cd6a6acSopenharmony_ci			if (strlen(OutfileName) == 0)
5346cd6a6acSopenharmony_ci				out_fp = stdout;
5356cd6a6acSopenharmony_ci			else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
5366cd6a6acSopenharmony_ci				fprintf(stderr, "Cannot open output file %s\n",
5376cd6a6acSopenharmony_ci					OutfileName);
5386cd6a6acSopenharmony_ci				out_fp = stdout;
5396cd6a6acSopenharmony_ci			}
5406cd6a6acSopenharmony_ci			if (out_fp != stdout)
5416cd6a6acSopenharmony_ci				printf("\nOutput to file: %s\n", OutfileName);
5426cd6a6acSopenharmony_ci			break;
5436cd6a6acSopenharmony_ci		case 'F':
5446cd6a6acSopenharmony_ci			display_filename_trans(&policydb, out_fp);
5456cd6a6acSopenharmony_ci			break;
5466cd6a6acSopenharmony_ci		case 'q':
5476cd6a6acSopenharmony_ci			policydb_destroy(&policydb);
5486cd6a6acSopenharmony_ci			exit(0);
5496cd6a6acSopenharmony_ci			break;
5506cd6a6acSopenharmony_ci		case 'm':
5516cd6a6acSopenharmony_ci			menu();
5526cd6a6acSopenharmony_ci			break;
5536cd6a6acSopenharmony_ci		default:
5546cd6a6acSopenharmony_ci			printf("\nInvalid choice\n");
5556cd6a6acSopenharmony_ci			menu();
5566cd6a6acSopenharmony_ci			break;
5576cd6a6acSopenharmony_ci
5586cd6a6acSopenharmony_ci		}
5596cd6a6acSopenharmony_ci	}
5606cd6a6acSopenharmony_ci}
5616cd6a6acSopenharmony_ci
5626cd6a6acSopenharmony_ci/* FLASK */
563