1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <getopt.h>
5#include <errno.h>
6#include <stdbool.h>
7#include <selinux/selinux.h>
8#include <selinux/label.h>
9
10static __attribute__ ((__noreturn__)) void usage(const char *progname)
11{
12	fprintf(stderr,
13		"usage:  %s [-v] -p <path> [-f file]\n\n"
14		"Where:\n\t"
15		"-v  Validate file_contxts entries against loaded policy.\n\t"
16		"-p  Path to check if a match or partial match is possible\n\t"
17		"    against a regex entry in the file_contexts file.\n\t"
18		"-f  Optional file_contexts file (defaults to current policy).\n\n"
19		"Example:\n\t"
20		"%s -p /sys/devices/system/cpu/online\n\t"
21		"   Check if a match or partial match is possible against\n\t"
22		"   the path \"/sys/devices/system/cpu/online\", returning\n\t"
23		"   TRUE or FALSE.\n\n", progname, progname);
24	exit(1);
25}
26
27int main(int argc, char **argv)
28{
29	int opt;
30	bool partial_match;
31	char *validate = NULL, *path = NULL, *file = NULL;
32
33	struct selabel_handle *hnd;
34	struct selinux_opt selabel_option[] = {
35		{ SELABEL_OPT_PATH, file },
36		{ SELABEL_OPT_VALIDATE, validate }
37	};
38
39	if (argc < 2)
40		usage(argv[0]);
41
42	while ((opt = getopt(argc, argv, "f:vp:")) > 0) {
43		switch (opt) {
44		case 'f':
45			file = optarg;
46			break;
47		case 'v':
48			validate = (char *)1;
49			break;
50		case 'p':
51			path = optarg;
52			break;
53		default:
54			usage(argv[0]);
55		}
56	}
57
58	selabel_option[0].value = file;
59	selabel_option[1].value = validate;
60
61	hnd = selabel_open(SELABEL_CTX_FILE, selabel_option, 2);
62	if (!hnd) {
63		fprintf(stderr, "ERROR: selabel_open - Could not obtain "
64							     "handle:  %s\n",
65							     strerror(errno));
66		return -1;
67	}
68
69	partial_match = selabel_partial_match(hnd, path);
70
71	printf("Match or Partial match: %s\n",
72		    partial_match == 1 ? "TRUE" : "FALSE");
73
74	selabel_close(hnd);
75	return partial_match;
76}
77