blob: 3b9a21698000ae1ccb7dc9aec46f53f749178969 [file] [log] [blame]
Robert Craigd98d26e2013-01-23 14:04:50 -05001#include <getopt.h>
Stephen Smalley01a58af2012-10-02 12:46:37 -04002#include <stdio.h>
3#include <stdlib.h>
Stephen Smalley13b6b7e2015-08-05 12:43:15 -04004#include <stdbool.h>
Stephen Smalley01a58af2012-10-02 12:46:37 -04005#include <sepol/sepol.h>
6#include <selinux/selinux.h>
7#include <selinux/label.h>
8
9static int nerr;
10
11static int validate(char **contextp)
12{
13 char *context = *contextp;
14 if (sepol_check_context(context) < 0) {
15 nerr++;
16 return -1;
17 }
18 return 0;
19}
20
Robert Craigd98d26e2013-01-23 14:04:50 -050021static void usage(char *name) {
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040022 fprintf(stderr, "usage1: %s [-p] sepolicy context_file\n\n", name);
Robert Craigd98d26e2013-01-23 14:04:50 -050023 fprintf(stderr, "Parses a context file and checks for syntax errors.\n");
24 fprintf(stderr, "The context_file is assumed to be a file_contexts file\n");
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040025 fprintf(stderr, "unless the -p option is used to indicate the property backend.\n\n");
26
27 fprintf(stderr, "usage2: %s -c file_contexts1 file_contexts2\n\n", name);
28 fprintf(stderr, "Compares two file contexts files and reports one of subset, equal, superset, or incomparable.\n");
Robert Craigd98d26e2013-01-23 14:04:50 -050029 fprintf(stderr, "\n");
30 exit(1);
31}
32
Stephen Smalley01a58af2012-10-02 12:46:37 -040033int main(int argc, char **argv)
34{
35 struct selinux_opt opts[] = {
36 { SELABEL_OPT_VALIDATE, (void*)1 },
37 { SELABEL_OPT_PATH, NULL }
38 };
Robert Craigd98d26e2013-01-23 14:04:50 -050039
40 // Default backend unless changed by input argument.
41 unsigned int backend = SELABEL_CTX_FILE;
42
Stephen Smalley01a58af2012-10-02 12:46:37 -040043 FILE *fp;
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040044 bool compare = false;
45 struct selabel_handle *sehnd[2];
Robert Craigd98d26e2013-01-23 14:04:50 -050046 char c;
Stephen Smalley01a58af2012-10-02 12:46:37 -040047
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040048 while ((c = getopt(argc, argv, "cph")) != -1) {
Robert Craigd98d26e2013-01-23 14:04:50 -050049 switch (c) {
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040050 case 'c':
51 compare = true;
52 break;
Robert Craigd98d26e2013-01-23 14:04:50 -050053 case 'p':
54 backend = SELABEL_CTX_ANDROID_PROP;
55 break;
56 case 'h':
57 default:
58 usage(argv[0]);
59 break;
60 }
Stephen Smalley01a58af2012-10-02 12:46:37 -040061 }
62
Robert Craigd98d26e2013-01-23 14:04:50 -050063 int index = optind;
64 if (argc - optind != 2) {
Robert Craigd98d26e2013-01-23 14:04:50 -050065 usage(argv[0]);
66 }
67
Stephen Smalley13b6b7e2015-08-05 12:43:15 -040068 if (compare && backend != SELABEL_CTX_FILE) {
69 usage(argv[0]);
70 }
71
72 if (compare) {
73 enum selabel_cmp_result result;
74 char *result_str[] = { "subset", "equal", "superset", "incomparable" };
75 int i;
76
77 opts[0].value = NULL; /* not validating against a policy when comparing */
78
79 for (i = 0; i < 2; i++) {
80 opts[1].value = argv[index+i];
81 sehnd[i] = selabel_open(backend, opts, 2);
82 if (!sehnd[i]) {
83 fprintf(stderr, "Error loading context file from %s\n", argv[index+i]);
84 exit(1);
85 }
86 }
87
88 result = selabel_cmp(sehnd[0], sehnd[1]);
89 for (i = 0; i < 2; i++)
90 selabel_close(sehnd[i]);
91 printf("%s\n", result_str[result]);
92 exit(0);
93 }
94
Robert Craigd98d26e2013-01-23 14:04:50 -050095 // remaining args are sepolicy file and context file
96 char *sepolicyFile = argv[index];
97 char *contextFile = argv[index + 1];
98
99 fp = fopen(sepolicyFile, "r");
Stephen Smalley01a58af2012-10-02 12:46:37 -0400100 if (!fp) {
Robert Craigd98d26e2013-01-23 14:04:50 -0500101 perror(sepolicyFile);
Stephen Smalley13b6b7e2015-08-05 12:43:15 -0400102 exit(1);
Stephen Smalley01a58af2012-10-02 12:46:37 -0400103 }
104 if (sepol_set_policydb_from_file(fp) < 0) {
Robert Craigd98d26e2013-01-23 14:04:50 -0500105 fprintf(stderr, "Error loading policy from %s\n", sepolicyFile);
Stephen Smalley13b6b7e2015-08-05 12:43:15 -0400106 exit(1);
Stephen Smalley01a58af2012-10-02 12:46:37 -0400107 }
108
109 selinux_set_callback(SELINUX_CB_VALIDATE,
110 (union selinux_callback)&validate);
111
Robert Craigd98d26e2013-01-23 14:04:50 -0500112 opts[1].value = contextFile;
Stephen Smalley01a58af2012-10-02 12:46:37 -0400113
Stephen Smalley13b6b7e2015-08-05 12:43:15 -0400114 sehnd[0] = selabel_open(backend, opts, 2);
115 if (!sehnd[0]) {
Robert Craigd98d26e2013-01-23 14:04:50 -0500116 fprintf(stderr, "Error loading context file from %s\n", contextFile);
Stephen Smalley13b6b7e2015-08-05 12:43:15 -0400117 exit(1);
Stephen Smalley01a58af2012-10-02 12:46:37 -0400118 }
119 if (nerr) {
Robert Craigd98d26e2013-01-23 14:04:50 -0500120 fprintf(stderr, "Invalid context file found in %s\n", contextFile);
Stephen Smalley13b6b7e2015-08-05 12:43:15 -0400121 exit(1);
Stephen Smalley01a58af2012-10-02 12:46:37 -0400122 }
Robert Craigd98d26e2013-01-23 14:04:50 -0500123
Stephen Smalley01a58af2012-10-02 12:46:37 -0400124 exit(0);
125}