113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Authors: Joshua Brindle <jbrindle@tresys.com>
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *	    Karl MacMillan <kmacmillan@tresys.com>
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *          Jason Tang     <jtang@tresys.com>
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2004-5 Tresys Technology, LLC
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *	This program is free software; you can redistribute it and/or modify
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  	it under the terms of the GNU General Public License as published by
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *	the Free Software Foundation, version 2.
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <getopt.h>
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h>
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h>
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/stat.h>
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fcntl.h>
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h>
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h>
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/mman.h>
22c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter#include <libgen.h>
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter#include <sepol/module_to_cil.h>
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h>
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/services.h>
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/conditional.h>
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/flask.h>
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/hierarchy.h>
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/expand.h>
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/link.h>
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/sidtab.h>
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "queue.h"
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "checkpolicy.h"
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "parse_util.h"
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleextern char *optarg;
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleextern int optind;
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic sidtab_t sidtab;
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleextern int mlspol;
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int handle_unknown = SEPOL_DENY_UNKNOWN;
467dcb7a594698124940d148f00f85be90c6757d7fNicolas Ioossstatic const char *txtfile = "policy.conf";
477dcb7a594698124940d148f00f85be90c6757d7fNicolas Ioossstatic const char *binfile = "policy";
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleunsigned int policy_type = POLICY_BASE;
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleunsigned int policyvers = MOD_POLICYDB_VERSION_MAX;
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
527dcb7a594698124940d148f00f85be90c6757d7fNicolas Ioossstatic int read_binary_policy(policydb_t * p, const char *file, const char *progname)
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int fd;
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct stat sb;
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void *map;
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct policy_file f, *fp;
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fd = open(file, O_RDONLY);
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0) {
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr, "Can't open '%s':  %s\n",
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			file, strerror(errno));
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fstat(fd, &sb) < 0) {
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr, "Can't stat '%s':  %s\n",
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			file, strerror(errno));
6887e8d46f2934d2d5591b44b29f308adb93f4b128Eric Paris		close(fd);
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	map =
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
7387e8d46f2934d2d5591b44b29f308adb93f4b128Eric Paris	close(fd);
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (map == MAP_FAILED) {
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr, "Can't map '%s':  %s\n", file, strerror(errno));
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policy_file_init(&f);
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	f.type = PF_USE_MEMORY;
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	f.data = map;
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	f.len = sb.st_size;
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fp = &f;
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (policydb_init(p)) {
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr, "%s:  policydb_init:  Out of memory!\n",
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			progname);
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (policydb_read(p, fp, 1)) {
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr,
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			"%s:  error(s) encountered while parsing configuration\n",
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			progname);
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Check Policy Consistency */
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (p->mls) {
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!mlspol) {
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s:  MLS policy, but non-MLS"
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				" is specified\n", progname);
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (mlspol) {
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s:  non-MLS policy, but MLS"
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				" is specified\n", progname);
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
113b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carterstatic int write_binary_policy(policydb_t * p, FILE *outfp)
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct policy_file pf;
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p->policy_type = policy_type;
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p->policyvers = policyvers;
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p->handle_unknown = handle_unknown;
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policy_file_init(&pf);
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	pf.type = PF_USE_STDIO;
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	pf.fp = outfp;
124b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	return policydb_write(p, &pf);
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
127ef61dd7d4b6d9acb480201670a4c540ba6521fa4Nicolas Ioossstatic __attribute__((__noreturn__)) void usage(const char *progname)
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
129b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	printf("usage:  %s [-h] [-V] [-b] [-C] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname);
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("Build base and policy modules.\n");
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("Options:\n");
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	       txtfile);
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -V         show policy versions created by this program\n");
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -b         treat input as a binary policy file\n");
136b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	printf("  -C         output CIL policy instead of binary policy\n");
13736fe4c35ee6b86d11db92f047120b3e38ff64fa9Daniel J Walsh	printf("  -h         print usage\n");
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -U OPTION  How to handle unknown classes and permissions\n");
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("               deny: Deny unknown kernel checks\n");
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("               reject: Reject loading of policy with unknowns\n");
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("               allow: Allow unknown kernel checks\n");
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -m         build a policy module instead of a base module\n");
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -M         enable MLS policy\n");
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("  -o FILE    write module to FILE (else just check syntax)\n");
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	exit(1);
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint main(int argc, char **argv)
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
1507dcb7a594698124940d148f00f85be90c6757d7fNicolas Iooss	const char *file = txtfile, *outfile = NULL;
151b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	unsigned int binary = 0, cil = 0;
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int ch;
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int show_version = 0;
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_t modpolicydb;
155bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia	struct option long_options[] = {
156bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{"help", no_argument, NULL, 'h'},
157bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{"output", required_argument, NULL, 'o'},
158bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{"binary", no_argument, NULL, 'b'},
159bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{"version", no_argument, NULL, 'V'},
160f6a03f1a3c5a545c1c3fd2914feb78b84d8012aeLaurent Bigonville		{"handle-unknown", required_argument, NULL, 'U'},
161bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{"mls", no_argument, NULL, 'M'},
162b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		{"cil", no_argument, NULL, 'C'},
163bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia		{NULL, 0, NULL, 0}
164bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia	};
165bf57d2349edec2cfe3d43eb71567a6b851bfc6cdGuido Trentalancia
166b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	while ((ch = getopt_long(argc, argv, "ho:bVU:mMC", long_options, NULL)) != -1) {
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		switch (ch) {
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'h':
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			usage(argv[0]);
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'o':
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			outfile = optarg;
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'b':
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			binary = 1;
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			file = binfile;
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'V':
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			show_version = 1;
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'U':
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (!strcasecmp(optarg, "deny")) {
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				handle_unknown = DENY_UNKNOWN;
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				break;
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (!strcasecmp(optarg, "reject")) {
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				handle_unknown = REJECT_UNKNOWN;
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				break;
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (!strcasecmp(optarg, "allow")) {
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				handle_unknown = ALLOW_UNKNOWN;
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				break;
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			usage(argv[0]);
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'm':
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policy_type = POLICY_MOD;
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policyvers = MOD_POLICYDB_VERSION_MAX;
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		case 'M':
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			mlspol = 1;
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
202b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		case 'C':
203b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			cil = 1;
204b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			break;
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		default:
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			usage(argv[0]);
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (show_version) {
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		printf("Module versions %d-%d\n",
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		exit(0);
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (handle_unknown && (policy_type != POLICY_BASE)) {
217bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley		fprintf(stderr, "%s:  Handling of unknown classes and permissions is only valid in the base module.\n", argv[0]);
218bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley		exit(1);
219bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley	}
220bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley
221bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley	if (binary && (policy_type != POLICY_BASE)) {
222bfb806120a0c973ba89f9070d499510216eb8409Stephen Smalley		fprintf(stderr, "%s:  -b and -m are incompatible with each other.\n", argv[0]);
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		exit(1);
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (optind != argc) {
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		file = argv[optind++];
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (optind != argc)
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			usage(argv[0]);
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("%s:  loading policy configuration from %s\n", argv[0], file);
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Set policydb and sidtab used by libsepol service functions
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	   to my structures, so that I can directly populate and
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	   manipulate them. */
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_set_policydb(&modpolicydb);
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_set_sidtab(&sidtab);
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (binary) {
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (read_binary_policy(&modpolicydb, file, argv[0]) == -1) {
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			exit(1);
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policydb_init(&modpolicydb)) {
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s: out of memory!\n", argv[0]);
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		modpolicydb.policy_type = policy_type;
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		modpolicydb.mls = mlspol;
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		modpolicydb.handle_unknown = handle_unknown;
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (read_source_policy(&modpolicydb, file, argv[0]) == -1) {
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			exit(1);
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (hierarchy_check_constraints(NULL, &modpolicydb)) {
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
262c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter	if (policy_type != POLICY_BASE && outfile) {
263c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		char *mod_name = modpolicydb.name;
264c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		char *out_path = strdup(outfile);
265c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		if (out_path == NULL) {
266c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter			fprintf(stderr, "%s:  out of memory\n", argv[0]);
267c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter			exit(1);
268c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		}
269c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		char *out_name = basename(out_path);
270c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		char *separator = strrchr(out_name, '.');
271c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		if (separator) {
272c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter			*separator = '\0';
273c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		}
274c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		if (strcmp(mod_name, out_name) != 0) {
275c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter			fprintf(stderr,	"%s:  Module name %s is different than the output base filename %s\n", argv[0], mod_name, out_name);
276c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter			exit(1);
277c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		}
278c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter		free(out_path);
279c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter	}
280c6acfae4bc22586ad1dc259b0aad57fa6c5b43efJames Carter
281b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	if (modpolicydb.policy_type == POLICY_BASE && !cil) {
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* Verify that we can successfully expand the base module. */
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_t kernpolicydb;
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policydb_init(&kernpolicydb)) {
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			exit(1);
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (link_modules(NULL, &modpolicydb, NULL, 0, 0)) {
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s:  link modules failed\n", argv[0]);
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			exit(1);
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "%s:  expand module failed\n", argv[0]);
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			exit(1);
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_destroy(&kernpolicydb);
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (policydb_load_isids(&modpolicydb, &sidtab))
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		exit(1);
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_sidtab_destroy(&sidtab);
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	printf("%s:  policy configuration loaded\n", argv[0]);
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
307b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	if (outfile) {
308b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		FILE *outfp = fopen(outfile, "w");
309b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
310b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		if (!outfp) {
311b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			perror(outfile);
312b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			exit(1);
313b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		}
314b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
315b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		if (!cil) {
316b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			printf("%s:  writing binary representation (version %d) to %s\n",
317b5f9debdb20e4aa1ddf940e7265237742cfca772Petr Lautrbach				   argv[0], policyvers, outfile);
318b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
319b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			if (write_binary_policy(&modpolicydb, outfp) != 0) {
320b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter				fprintf(stderr, "%s:  error writing %s\n", argv[0], outfile);
321b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter				exit(1);
322b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			}
323b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		} else {
324b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			printf("%s:  writing CIL to %s\n",argv[0], outfile);
325b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
326b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			if (sepol_module_policydb_to_cil(outfp, &modpolicydb, 0) != 0) {
327b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter				fprintf(stderr, "%s:  error writing %s\n", argv[0], outfile);
328b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter				exit(1);
329b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter			}
330b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		}
331b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
332b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		fclose(outfp);
333b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter	} else if (cil) {
334b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter		fprintf(stderr, "%s:  No file to write CIL was specified\n", argv[0]);
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		exit(1);
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
337b1d94562953947f85fd79f20bc4477aa5e01e2c4James Carter
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_destroy(&modpolicydb);
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* FLASK */
344