• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Authors: Karl MacMillan <kmacmillan@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 
usage(const char * prog)25 static __attribute__((__noreturn__)) 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 
file_to_policy_file(const char * filename,struct sepol_policy_file ** pf,const char * mode)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 
file_to_data(const char * path,char ** data,size_t * len)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 	if (!sb.st_size) {
76 		close(fd);
77 		*len = 0;
78 		return 0;
79 	}
80 
81 	*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
82 	if (*data == MAP_FAILED) {
83 		fprintf(stderr, "%s:  Failed to mmap %s:  %s\n", progname, path,
84 			strerror(errno));
85 		goto err;
86 	}
87 	*len = sb.st_size;
88 	close(fd);
89 	return 0;
90       err:
91 	close(fd);
92 	return -1;
93 }
94 
main(int argc,char ** argv)95 int main(int argc, char **argv)
96 {
97 	struct sepol_module_package *pkg;
98 	struct sepol_policy_file *mod, *out;
99 	char *module = NULL, *file_contexts = NULL, *seusers =
100 	    NULL, *user_extra = NULL;
101 	char *fcdata = NULL, *outfile = NULL, *seusersdata =
102 	    NULL, *user_extradata = NULL;
103 	char *netfilter_contexts = NULL, *ncdata = NULL;
104 	size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
105 	int i;
106 
107 	static struct option opts[] = {
108 		{"module", required_argument, NULL, 'm'},
109 		{"fc", required_argument, NULL, 'f'},
110 		{"seuser", required_argument, NULL, 's'},
111 		{"user_extra", required_argument, NULL, 'u'},
112 		{"nc", required_argument, NULL, 'n'},
113 		{"outfile", required_argument, NULL, 'o'},
114 		{"help", 0, NULL, 'h'},
115 		{NULL, 0, NULL, 0}
116 	};
117 
118 	while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
119 		switch (i) {
120 		case 'h':
121 			usage(argv[0]);
122 			exit(0);
123 		case 'm':
124 			if (module) {
125 				fprintf(stderr,
126 					"May not specify more than one module\n");
127 				exit(1);
128 			}
129 			module = strdup(optarg);
130 			if (!module)
131 				exit(1);
132 			break;
133 		case 'f':
134 			if (file_contexts) {
135 				fprintf(stderr,
136 					"May not specify more than one file context file\n");
137 				exit(1);
138 			}
139 			file_contexts = strdup(optarg);
140 			if (!file_contexts)
141 				exit(1);
142 			break;
143 		case 'o':
144 			if (outfile) {
145 				fprintf(stderr,
146 					"May not specify more than one output file\n");
147 				exit(1);
148 			}
149 			outfile = strdup(optarg);
150 			if (!outfile)
151 				exit(1);
152 			break;
153 		case 's':
154 			if (seusers) {
155 				fprintf(stderr,
156 					"May not specify more than one seuser file\n");
157 				exit(1);
158 			}
159 			seusers = strdup(optarg);
160 			if (!seusers)
161 				exit(1);
162 			break;
163 		case 'u':
164 			if (user_extra) {
165 				fprintf(stderr,
166 					"May not specify more than one user_extra file\n");
167 				exit(1);
168 			}
169 			user_extra = strdup(optarg);
170 			if (!user_extra)
171 				exit(1);
172 			break;
173 		case 'n':
174 			if (netfilter_contexts) {
175 				fprintf(stderr,
176 					"May not specify more than one netfilter contexts file\n");
177 				exit(1);
178 			}
179 			netfilter_contexts = strdup(optarg);
180 			if (!netfilter_contexts)
181 				exit(1);
182 			break;
183 		}
184 	}
185 
186 	progname = argv[0];
187 
188 	if (!module || !outfile) {
189 		usage(argv[0]);
190 		exit(0);
191 	}
192 
193 	if (file_contexts) {
194 		if (file_to_data(file_contexts, &fcdata, &fclen))
195 			exit(1);
196 	}
197 
198 	if (seusers) {
199 		if (file_to_data(seusers, &seusersdata, &seuserslen))
200 			exit(1);
201 	}
202 
203 	if (user_extra) {
204 		if (file_to_data(user_extra, &user_extradata, &user_extralen))
205 			exit(1);
206 	}
207 
208 	if (netfilter_contexts) {
209 		if (file_to_data(netfilter_contexts, &ncdata, &nclen))
210 			exit(1);
211 	}
212 
213 	if (file_to_policy_file(module, &mod, "r"))
214 		exit(1);
215 
216 	if (sepol_module_package_create(&pkg)) {
217 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
218 		exit(1);
219 	}
220 
221 	if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
222 		fprintf(stderr,
223 			"%s:  Error while reading policy module from %s\n",
224 			argv[0], module);
225 		exit(1);
226 	}
227 
228 	if (fclen)
229 		sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
230 
231 	if (seuserslen)
232 		sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
233 
234 	if (user_extra)
235 		sepol_module_package_set_user_extra(pkg, user_extradata,
236 						    user_extralen);
237 
238 	if (nclen)
239 		sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
240 
241 	if (file_to_policy_file(outfile, &out, "w"))
242 		exit(1);
243 
244 	if (sepol_module_package_write(pkg, out)) {
245 		fprintf(stderr,
246 			"%s:  Error while writing module package to %s\n",
247 			argv[0], argv[1]);
248 		exit(1);
249 	}
250 
251 	if (fclen)
252 		munmap(fcdata, fclen);
253 	if (nclen)
254 		munmap(ncdata, nclen);
255 	sepol_policy_file_free(mod);
256 	sepol_policy_file_free(out);
257 	sepol_module_package_free(pkg);
258 	free(file_contexts);
259 	free(outfile);
260 	free(module);
261 	free(seusers);
262 	free(user_extra);
263 	exit(0);
264 }
265