blob: eb256a3046d650e0e7add537851c50ec09935928 [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>
4#include <sepol/sepol.h>
5#include <selinux/selinux.h>
6#include <selinux/label.h>
7
8static int nerr;
9
10static int validate(char **contextp)
11{
12 char *context = *contextp;
13 if (sepol_check_context(context) < 0) {
14 nerr++;
15 return -1;
16 }
17 return 0;
18}
19
Robert Craigd98d26e2013-01-23 14:04:50 -050020static void usage(char *name) {
21 fprintf(stderr, "usage: %s [OPTIONS] sepolicy context_file\n\n", name);
22 fprintf(stderr, "Parses a context file and checks for syntax errors.\n");
23 fprintf(stderr, "The context_file is assumed to be a file_contexts file\n");
24 fprintf(stderr, "unless explicitly switched by an option.\n\n");
25 fprintf(stderr, " OPTIONS:\n");
26 fprintf(stderr, " -p : context file represents a property_context file.\n");
27 fprintf(stderr, "\n");
28 exit(1);
29}
30
Stephen Smalley01a58af2012-10-02 12:46:37 -040031int main(int argc, char **argv)
32{
33 struct selinux_opt opts[] = {
34 { SELABEL_OPT_VALIDATE, (void*)1 },
35 { SELABEL_OPT_PATH, NULL }
36 };
Robert Craigd98d26e2013-01-23 14:04:50 -050037
38 // Default backend unless changed by input argument.
39 unsigned int backend = SELABEL_CTX_FILE;
40
Stephen Smalley01a58af2012-10-02 12:46:37 -040041 FILE *fp;
42 struct selabel_handle *sehnd;
Robert Craigd98d26e2013-01-23 14:04:50 -050043 char c;
Stephen Smalley01a58af2012-10-02 12:46:37 -040044
Robert Craigd98d26e2013-01-23 14:04:50 -050045 while ((c = getopt(argc, argv, "ph")) != -1) {
46 switch (c) {
47 case 'p':
48 backend = SELABEL_CTX_ANDROID_PROP;
49 break;
50 case 'h':
51 default:
52 usage(argv[0]);
53 break;
54 }
Stephen Smalley01a58af2012-10-02 12:46:37 -040055 }
56
Robert Craigd98d26e2013-01-23 14:04:50 -050057 int index = optind;
58 if (argc - optind != 2) {
59 fprintf(stderr, "Expected sepolicy file and context file as arguments.\n");
60 usage(argv[0]);
61 }
62
63 // remaining args are sepolicy file and context file
64 char *sepolicyFile = argv[index];
65 char *contextFile = argv[index + 1];
66
67 fp = fopen(sepolicyFile, "r");
Stephen Smalley01a58af2012-10-02 12:46:37 -040068 if (!fp) {
Robert Craigd98d26e2013-01-23 14:04:50 -050069 perror(sepolicyFile);
Stephen Smalley01a58af2012-10-02 12:46:37 -040070 exit(2);
71 }
72 if (sepol_set_policydb_from_file(fp) < 0) {
Robert Craigd98d26e2013-01-23 14:04:50 -050073 fprintf(stderr, "Error loading policy from %s\n", sepolicyFile);
Stephen Smalley01a58af2012-10-02 12:46:37 -040074 exit(3);
75 }
76
77 selinux_set_callback(SELINUX_CB_VALIDATE,
78 (union selinux_callback)&validate);
79
Robert Craigd98d26e2013-01-23 14:04:50 -050080 opts[1].value = contextFile;
Stephen Smalley01a58af2012-10-02 12:46:37 -040081
Robert Craigd98d26e2013-01-23 14:04:50 -050082 sehnd = selabel_open(backend, opts, 2);
Stephen Smalley01a58af2012-10-02 12:46:37 -040083 if (!sehnd) {
Robert Craigd98d26e2013-01-23 14:04:50 -050084 fprintf(stderr, "Error loading context file from %s\n", contextFile);
Stephen Smalley01a58af2012-10-02 12:46:37 -040085 exit(4);
86 }
87 if (nerr) {
Robert Craigd98d26e2013-01-23 14:04:50 -050088 fprintf(stderr, "Invalid context file found in %s\n", contextFile);
Stephen Smalley01a58af2012-10-02 12:46:37 -040089 exit(5);
90 }
Robert Craigd98d26e2013-01-23 14:04:50 -050091
Stephen Smalley01a58af2012-10-02 12:46:37 -040092 exit(0);
93}