Home | History | Annotate | Download | only in semodule_package
      1 /* Authors: Karl MacMillan <kmacmillan (at) tresys.com>
      2  *
      3  * Copyright (C) 2004 Tresys Technology, LLC
      4  *	This program is free software; you can redistribute it and/or modify
      5  *  	it under the terms of the GNU General Public License as published by
      6  *	the Free Software Foundation, version 2.
      7  */
      8 
      9 #include <sepol/module.h>
     10 #include <getopt.h>
     11 #include <fcntl.h>
     12 #include <stdio.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 #include <sys/mman.h>
     19 #include <fcntl.h>
     20 #include <errno.h>
     21 
     22 char *progname = NULL;
     23 extern char *optarg;
     24 
     25 static void usage(const char *prog)
     26 {
     27 	printf("usage: %s -o <output file> -m <module> [-f <file contexts>]\n",
     28 	       prog);
     29 	printf("Options:\n");
     30 	printf("  -o --outfile		Output file (required)\n");
     31 	printf("  -m --module		Module file (required)\n");
     32 	printf("  -f --fc		File contexts file\n");
     33 	printf("  -s --seuser		Seusers file (only valid in base)\n");
     34 	printf
     35 	    ("  -u --user_extra	user_extra file (only valid in base)\n");
     36 	printf("  -n --nc		Netfilter contexts file\n");
     37 	exit(1);
     38 }
     39 
     40 static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
     41 			       const char *mode)
     42 {
     43 	FILE *f;
     44 
     45 	if (sepol_policy_file_create(pf)) {
     46 		fprintf(stderr, "%s:  Out of memory\n", progname);
     47 		return -1;
     48 	}
     49 
     50 	f = fopen(filename, mode);
     51 	if (!f) {
     52 		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
     53 			strerror(errno), filename);
     54 		return -1;
     55 	}
     56 	sepol_policy_file_set_fp(*pf, f);
     57 	return 0;
     58 }
     59 
     60 static int file_to_data(const char *path, char **data, size_t * len)
     61 {
     62 	int fd;
     63 	struct stat sb;
     64 	fd = open(path, O_RDONLY);
     65 	if (fd < 0) {
     66 		fprintf(stderr, "%s:  Failed to open %s:  %s\n", progname, path,
     67 			strerror(errno));
     68 		return -1;
     69 	}
     70 	if (fstat(fd, &sb) < 0) {
     71 		fprintf(stderr, "%s:  Failed to fstat %s:  %s\n", progname,
     72 			path, strerror(errno));
     73 		goto err;
     74 	}
     75 
     76 	*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
     77 	if (*data == MAP_FAILED) {
     78 		fprintf(stderr, "%s:  Failed to mmap %s:  %s\n", progname, path,
     79 			strerror(errno));
     80 		goto err;
     81 	}
     82 	*len = sb.st_size;
     83 	close(fd);
     84 	return 0;
     85       err:
     86 	close(fd);
     87 	return -1;
     88 }
     89 
     90 int main(int argc, char **argv)
     91 {
     92 	struct sepol_module_package *pkg;
     93 	struct sepol_policy_file *mod, *out;
     94 	char *module = NULL, *file_contexts = NULL, *seusers =
     95 	    NULL, *user_extra = NULL;
     96 	char *fcdata = NULL, *outfile = NULL, *seusersdata =
     97 	    NULL, *user_extradata = NULL;
     98 	char *netfilter_contexts = NULL, *ncdata = NULL;
     99 	size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
    100 	int i;
    101 
    102 	static struct option opts[] = {
    103 		{"module", required_argument, NULL, 'm'},
    104 		{"fc", required_argument, NULL, 'f'},
    105 		{"seuser", required_argument, NULL, 's'},
    106 		{"user_extra", required_argument, NULL, 'u'},
    107 		{"nc", required_argument, NULL, 'n'},
    108 		{"outfile", required_argument, NULL, 'o'},
    109 		{"help", 0, NULL, 'h'},
    110 		{NULL, 0, NULL, 0}
    111 	};
    112 
    113 	while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
    114 		switch (i) {
    115 		case 'h':
    116 			usage(argv[0]);
    117 			exit(0);
    118 		case 'm':
    119 			if (module) {
    120 				fprintf(stderr,
    121 					"May not specify more than one module\n");
    122 				exit(1);
    123 			}
    124 			module = strdup(optarg);
    125 			if (!module)
    126 				exit(1);
    127 			break;
    128 		case 'f':
    129 			if (file_contexts) {
    130 				fprintf(stderr,
    131 					"May not specify more than one file context file\n");
    132 				exit(1);
    133 			}
    134 			file_contexts = strdup(optarg);
    135 			if (!file_contexts)
    136 				exit(1);
    137 			break;
    138 		case 'o':
    139 			if (outfile) {
    140 				fprintf(stderr,
    141 					"May not specify more than one output file\n");
    142 				exit(1);
    143 			}
    144 			outfile = strdup(optarg);
    145 			if (!outfile)
    146 				exit(1);
    147 			break;
    148 		case 's':
    149 			if (seusers) {
    150 				fprintf(stderr,
    151 					"May not specify more than one seuser file\n");
    152 				exit(1);
    153 			}
    154 			seusers = strdup(optarg);
    155 			if (!seusers)
    156 				exit(1);
    157 			break;
    158 		case 'u':
    159 			if (user_extra) {
    160 				fprintf(stderr,
    161 					"May not specify more than one user_extra file\n");
    162 				exit(1);
    163 			}
    164 			user_extra = strdup(optarg);
    165 			if (!user_extra)
    166 				exit(1);
    167 			break;
    168 		case 'n':
    169 			if (netfilter_contexts) {
    170 				fprintf(stderr,
    171 					"May not specify more than one netfilter contexts file\n");
    172 				exit(1);
    173 			}
    174 			netfilter_contexts = strdup(optarg);
    175 			if (!netfilter_contexts)
    176 				exit(1);
    177 			break;
    178 		}
    179 	}
    180 
    181 	progname = argv[0];
    182 
    183 	if (!module || !outfile) {
    184 		usage(argv[0]);
    185 		exit(0);
    186 	}
    187 
    188 	if (file_contexts) {
    189 		if (file_to_data(file_contexts, &fcdata, &fclen))
    190 			exit(1);
    191 	}
    192 
    193 	if (seusers) {
    194 		if (file_to_data(seusers, &seusersdata, &seuserslen))
    195 			exit(1);
    196 	}
    197 
    198 	if (user_extra) {
    199 		if (file_to_data(user_extra, &user_extradata, &user_extralen))
    200 			exit(1);
    201 	}
    202 
    203 	if (netfilter_contexts) {
    204 		if (file_to_data(netfilter_contexts, &ncdata, &nclen))
    205 			exit(1);
    206 	}
    207 
    208 	if (file_to_policy_file(module, &mod, "r"))
    209 		exit(1);
    210 
    211 	if (sepol_module_package_create(&pkg)) {
    212 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
    213 		exit(1);
    214 	}
    215 
    216 	if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
    217 		fprintf(stderr,
    218 			"%s:  Error while reading policy module from %s\n",
    219 			argv[0], module);
    220 		exit(1);
    221 	}
    222 
    223 	if (fclen)
    224 		sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
    225 
    226 	if (seuserslen)
    227 		sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
    228 
    229 	if (user_extra)
    230 		sepol_module_package_set_user_extra(pkg, user_extradata,
    231 						    user_extralen);
    232 
    233 	if (nclen)
    234 		sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
    235 
    236 	if (file_to_policy_file(outfile, &out, "w"))
    237 		exit(1);
    238 
    239 	if (sepol_module_package_write(pkg, out)) {
    240 		fprintf(stderr,
    241 			"%s:  Error while writing module package to %s\n",
    242 			argv[0], argv[1]);
    243 		exit(1);
    244 	}
    245 
    246 	if (fclen)
    247 		munmap(fcdata, fclen);
    248 	if (nclen)
    249 		munmap(ncdata, nclen);
    250 	sepol_policy_file_free(mod);
    251 	sepol_policy_file_free(out);
    252 	sepol_module_package_free(pkg);
    253 	free(file_contexts);
    254 	free(outfile);
    255 	free(module);
    256 	exit(0);
    257 }
    258