2013-01-23 20:04:50 +01:00
|
|
|
#include <getopt.h>
|
2012-10-02 18:46:37 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sepol/sepol.h>
|
|
|
|
#include <selinux/selinux.h>
|
|
|
|
#include <selinux/label.h>
|
|
|
|
|
|
|
|
static int nerr;
|
|
|
|
|
|
|
|
static int validate(char **contextp)
|
|
|
|
{
|
|
|
|
char *context = *contextp;
|
|
|
|
if (sepol_check_context(context) < 0) {
|
|
|
|
nerr++;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-23 20:04:50 +01:00
|
|
|
static void usage(char *name) {
|
|
|
|
fprintf(stderr, "usage: %s [OPTIONS] sepolicy context_file\n\n", name);
|
|
|
|
fprintf(stderr, "Parses a context file and checks for syntax errors.\n");
|
|
|
|
fprintf(stderr, "The context_file is assumed to be a file_contexts file\n");
|
|
|
|
fprintf(stderr, "unless explicitly switched by an option.\n\n");
|
|
|
|
fprintf(stderr, " OPTIONS:\n");
|
|
|
|
fprintf(stderr, " -p : context file represents a property_context file.\n");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-10-02 18:46:37 +02:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct selinux_opt opts[] = {
|
|
|
|
{ SELABEL_OPT_VALIDATE, (void*)1 },
|
|
|
|
{ SELABEL_OPT_PATH, NULL }
|
|
|
|
};
|
2013-01-23 20:04:50 +01:00
|
|
|
|
|
|
|
// Default backend unless changed by input argument.
|
|
|
|
unsigned int backend = SELABEL_CTX_FILE;
|
|
|
|
|
2012-10-02 18:46:37 +02:00
|
|
|
FILE *fp;
|
|
|
|
struct selabel_handle *sehnd;
|
2013-01-23 20:04:50 +01:00
|
|
|
char c;
|
2012-10-02 18:46:37 +02:00
|
|
|
|
2013-01-23 20:04:50 +01:00
|
|
|
while ((c = getopt(argc, argv, "ph")) != -1) {
|
|
|
|
switch (c) {
|
|
|
|
case 'p':
|
|
|
|
backend = SELABEL_CTX_ANDROID_PROP;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
default:
|
|
|
|
usage(argv[0]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = optind;
|
|
|
|
if (argc - optind != 2) {
|
|
|
|
fprintf(stderr, "Expected sepolicy file and context file as arguments.\n");
|
|
|
|
usage(argv[0]);
|
2012-10-02 18:46:37 +02:00
|
|
|
}
|
|
|
|
|
2013-01-23 20:04:50 +01:00
|
|
|
// remaining args are sepolicy file and context file
|
|
|
|
char *sepolicyFile = argv[index];
|
|
|
|
char *contextFile = argv[index + 1];
|
|
|
|
|
|
|
|
fp = fopen(sepolicyFile, "r");
|
2012-10-02 18:46:37 +02:00
|
|
|
if (!fp) {
|
2013-01-23 20:04:50 +01:00
|
|
|
perror(sepolicyFile);
|
2012-10-02 18:46:37 +02:00
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
if (sepol_set_policydb_from_file(fp) < 0) {
|
2013-01-23 20:04:50 +01:00
|
|
|
fprintf(stderr, "Error loading policy from %s\n", sepolicyFile);
|
2012-10-02 18:46:37 +02:00
|
|
|
exit(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
selinux_set_callback(SELINUX_CB_VALIDATE,
|
|
|
|
(union selinux_callback)&validate);
|
|
|
|
|
2013-01-23 20:04:50 +01:00
|
|
|
opts[1].value = contextFile;
|
2012-10-02 18:46:37 +02:00
|
|
|
|
2013-01-23 20:04:50 +01:00
|
|
|
sehnd = selabel_open(backend, opts, 2);
|
2012-10-02 18:46:37 +02:00
|
|
|
if (!sehnd) {
|
2013-01-23 20:04:50 +01:00
|
|
|
fprintf(stderr, "Error loading context file from %s\n", contextFile);
|
2012-10-02 18:46:37 +02:00
|
|
|
exit(4);
|
|
|
|
}
|
|
|
|
if (nerr) {
|
2013-01-23 20:04:50 +01:00
|
|
|
fprintf(stderr, "Invalid context file found in %s\n", contextFile);
|
2012-10-02 18:46:37 +02:00
|
|
|
exit(5);
|
|
|
|
}
|
2013-01-23 20:04:50 +01:00
|
|
|
|
2012-10-02 18:46:37 +02:00
|
|
|
exit(0);
|
|
|
|
}
|