101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <getopt.h>
201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <unistd.h>
301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <stdlib.h>
401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <sys/mman.h>
501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <sys/types.h>
601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <sys/stat.h>
701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <fcntl.h>
801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <stdio.h>
901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <sepol/policydb/policydb.h>
1001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#include <sepol/policydb/services.h>
11640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley#include <sepol/policydb/expand.h>
1201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
1301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#define EQUALS 0
1401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#define NOT 1
1501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra#define ANY 2
1601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
1701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condravoid usage(char *arg0) {
1801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	fprintf(stderr, "%s -s <source> -t <target> -c <class> -p <perm> -P <policy file>\n", arg0);
1901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	exit(1);
2001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
2101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
2201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condravoid *cmalloc(size_t s) {
2301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	void *t = malloc(s);
2401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (t == NULL) {
2501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Out of memory\n");
2601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		exit(1);
2701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
2801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	return t;
2901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
3001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
3101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint parse_ops(char **arg) {
3201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	switch (*arg[0]) {
3301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		case '-':
3401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			*arg = *arg + 1;
3501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return NOT;
3601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		case '*':
3701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return ANY;
3801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		default:
3901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return EQUALS;
4001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
4101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
4201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
4301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint check(int op, uint16_t arg1, uint16_t arg2) {
4401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	switch (op) {
4501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		case EQUALS:
4601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return arg1 == arg2;
4701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		case NOT:
4801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return arg1 != arg2;
4901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		case ANY:
5001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return 1;
5101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		default:
5201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			fprintf(stderr, "Bad op while checking!");
5301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return 2;
5401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
5501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
5601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
5701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint check_perm(avtab_ptr_t current, perm_datum_t *perm) {
5801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	uint16_t perm_bitmask = 1U << (perm->s.value - 1);
5901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	return (current->datum.data & perm_bitmask) != 0;
6001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
6101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
62640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
63640991bb3c8a7552a781bc0db544923901583de6Stephen Smalleyint expand_and_check(int s_op, uint32_t source_type,
64640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		     int t_op, uint32_t target_type,
65640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		     int c_op, uint32_t target_class,
66640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		     perm_datum_t *perm, policydb_t *policy, avtab_t *avtab) {
67640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	avtab_t exp_avtab;
68640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	avtab_ptr_t cur;
69640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	unsigned int i;
70640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	int match;
71640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
72640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	if (avtab_init(&exp_avtab)) {
73640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		fputs("out of memory\n", stderr);
74640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		return -1;
75640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	}
76640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
77640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	if (expand_avtab(policy, avtab, &exp_avtab)) {
78640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		fputs("out of memory\n", stderr);
79640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		avtab_destroy(&exp_avtab);
80640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		return -1;
81640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	}
82640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
83640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	for (i = 0; i < exp_avtab.nslot; i++) {
84640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		for (cur = exp_avtab.htable[i]; cur; cur = cur->next) {
85640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			match = 1;
86640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			match &= check(s_op, source_type, cur->key.source_type);
87640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			match &= check(t_op, target_type, cur->key.target_type);
88640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			match &= check(c_op, target_class, cur->key.target_class);
89640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			match &= check_perm(cur, perm);
90640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			if (match) {
91640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				avtab_destroy(&exp_avtab);
92640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				return 1;
93640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley			}
94640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		}
95640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	}
96640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
97640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	avtab_destroy(&exp_avtab);
98640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	return 0;
99640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley}
100640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley
10101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra/*
10201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * Checks to see if a rule matching the given arguments already exists.
10301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra *
10401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * The format for the arguments is as follows:
10501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra *
10601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - A bare string is treated as a literal and will be matched by equality.
10701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - A string starting with "-" will be matched by inequality.
10801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - A string starting with "*" will be treated as a wildcard.
10901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra *
11001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * The return codes for this function are as follows:
11101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra *
11201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - 0 indicates a successful return without a match
11301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - 1 indicates a successful return with a match
11401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra * - -1 indicates an error
11501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra */
11601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint check_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {
11701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	type_datum_t *src = NULL;
11801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	type_datum_t *tgt = NULL;
11901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	class_datum_t *cls = NULL;
12001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	perm_datum_t *perm = NULL;
12101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int s_op = parse_ops(&s);
12201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int t_op = parse_ops(&t);
12301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int c_op = parse_ops(&c);
12401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int p_op = parse_ops(&p);
12501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	avtab_key_t key;
12601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int match;
12701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
1287b2bee99c18b8cb3f52161b1191d16b8ab50b08fStephen Smalley	key.source_type = key.target_type = key.target_class = 0;
1297b2bee99c18b8cb3f52161b1191d16b8ab50b08fStephen Smalley
13001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (s_op != ANY) {
13101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		src = hashtab_search(policy->p_types.table, s);
13201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		if (src == NULL) {
13301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			fprintf(stderr, "source type %s does not exist\n", s);
13401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return -1;
13501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		}
13601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
13701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (t_op != ANY) {
13801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		tgt = hashtab_search(policy->p_types.table, t);
13901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		if (tgt == NULL) {
14001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			fprintf(stderr, "target type %s does not exist\n", t);
14101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return -1;
14201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		}
14301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
14401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (c_op != ANY) {
14501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		cls = hashtab_search(policy->p_classes.table, c);
14601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		if (cls == NULL) {
14701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			fprintf(stderr, "class %s does not exist\n", c);
14801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			return -1;
14901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		}
15001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
15101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (p_op != ANY) {
15201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		perm = hashtab_search(cls->permissions.table, p);
15301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		if (perm == NULL) {
15401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			if (cls->comdatum == NULL) {
15501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
15601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				return -1;
15701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			}
15801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			perm = hashtab_search(cls->comdatum->permissions.table, p);
15901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			if (perm == NULL) {
16001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
16101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				return -1;
16201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			}
16301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		}
16401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
16501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
16601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (s_op != ANY)
16701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		key.source_type = src->s.value;
16801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (t_op != ANY)
16901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		key.target_type = tgt->s.value;
17001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (c_op != ANY)
17101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		key.target_class = cls->s.value;
17201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
173640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	/* Check unconditional rules after attribute expansion. */
174640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	match = expand_and_check(s_op, key.source_type,
175640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				 t_op, key.target_type,
176640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				 c_op, key.target_class,
177640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				 perm, policy, &policy->te_avtab);
178640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	if (match)
179640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley		return match;
18001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
181640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	/* Check conditional rules after attribute expansion. */
182640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley	return expand_and_check(s_op, key.source_type,
183640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				t_op, key.target_type,
184640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				c_op, key.target_class,
185640991bb3c8a7552a781bc0db544923901583de6Stephen Smalley				perm, policy, &policy->te_cond_avtab);
18601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
18701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
18801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) {
18901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int fd;
19001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	struct stat sb;
19101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	void *map;
19201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int ret;
19301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
19401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	fd = open(filename, O_RDONLY);
19501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (fd < 0) {
19601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Can't open '%s':  %s\n", filename, strerror(errno));
19701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		return 1;
19801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
19901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (fstat(fd, &sb) < 0) {
20001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Can't stat '%s':  %s\n", filename, strerror(errno));
20101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		close(fd);
20201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		return 1;
20301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
20401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
20501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (map == MAP_FAILED) {
20601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Can't mmap '%s':  %s\n", filename, strerror(errno));
20701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		close(fd);
20801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		return 1;
20901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
21001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
21101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	policy_file_init(pf);
21201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	pf->type = PF_USE_MEMORY;
21301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	pf->data = map;
21401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	pf->len = sb.st_size;
21501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (policydb_init(policydb)) {
21601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Could not initialize policydb!\n");
21701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		close(fd);
21801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		munmap(map, sb.st_size);
21901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		return 1;
22001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
22101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	ret = policydb_read(policydb, pf, 0);
22201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (ret) {
22301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "error(s) encountered while parsing configuration\n");
22401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		close(fd);
22501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		munmap(map, sb.st_size);
22601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		return 1;
22701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
22801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
22901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	return 0;
23001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
23101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
23201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
23301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraint main(int argc, char **argv)
23401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra{
23501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	char *policy = NULL, *source = NULL, *target = NULL, *class = NULL, *perm = NULL;
23601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	policydb_t policydb;
23701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	struct policy_file pf;
23801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	sidtab_t sidtab;
23901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	char ch;
24001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	int match = 1;
24101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
24201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	struct option long_options[] = {
24301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{"source", required_argument, NULL, 's'},
24401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{"target", required_argument, NULL, 't'},
24501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{"class", required_argument, NULL, 'c'},
24601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{"perm", required_argument, NULL, 'p'},
24701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{"policy", required_argument, NULL, 'P'},
24801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			{NULL, 0, NULL, 0}
24901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	};
25001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
25101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	while ((ch = getopt_long(argc, argv, "s:t:c:p:P:", long_options, NULL)) != -1) {
25201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		switch (ch) {
25301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			case 's':
25401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				source = optarg;
25501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				break;
25601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			case 't':
25701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				target = optarg;
25801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				break;
25901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			case 'c':
26001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				class = optarg;
26101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				break;
26201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			case 'p':
26301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				perm = optarg;
26401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				break;
26501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			case 'P':
26601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				policy = optarg;
26701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				break;
26801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra			default:
26901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra				usage(argv[0]);
27001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		}
27101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
27201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
27301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (!source || !target || !class || !perm || !policy)
27401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		usage(argv[0]);
27501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
27601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	sepol_set_policydb(&policydb);
27701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	sepol_set_sidtab(&sidtab);
27801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
27901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (load_policy(policy, &policydb, &pf))
28001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		goto out;
28101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
28201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	match = check_rule(source, target, class, perm, &policydb);
28301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	if (match < 0) {
28401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		fprintf(stderr, "Error checking rules!\n");
28501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		goto out;
28601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	} else if (match > 0) {
28701aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		printf("Match found!\n");
28801aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra		goto out;
28901aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	}
29001aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
29101aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	match = 0;
29201aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra
29301aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condraout:
29401aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	policydb_destroy(&policydb);
29501aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra	return match;
29601aaeb6a82ca23744fd629e8522697f0fcac8c13Geremy Condra}
297