Blame semodule-utils/semodule_package/semodule_package.c

Packit Service 9fb14c
/* Authors: Karl MacMillan <kmacmillan@tresys.com>
Packit Service 9fb14c
 *
Packit Service 9fb14c
 * Copyright (C) 2004 Tresys Technology, LLC
Packit Service 9fb14c
 *	This program is free software; you can redistribute it and/or modify
Packit Service 9fb14c
 *  	it under the terms of the GNU General Public License as published by
Packit Service 9fb14c
 *	the Free Software Foundation, version 2.
Packit Service 9fb14c
 */
Packit Service 9fb14c
Packit Service 9fb14c
#include <sepol/module.h>
Packit Service 9fb14c
#include <getopt.h>
Packit Service 9fb14c
#include <fcntl.h>
Packit Service 9fb14c
#include <stdio.h>
Packit Service 9fb14c
#include <stdlib.h>
Packit Service 9fb14c
#include <string.h>
Packit Service 9fb14c
#include <unistd.h>
Packit Service 9fb14c
#include <sys/types.h>
Packit Service 9fb14c
#include <sys/stat.h>
Packit Service 9fb14c
#include <sys/mman.h>
Packit Service 9fb14c
#include <fcntl.h>
Packit Service 9fb14c
#include <errno.h>
Packit Service 9fb14c
Packit Service 9fb14c
char *progname = NULL;
Packit Service 9fb14c
extern char *optarg;
Packit Service 9fb14c
Packit Service 9fb14c
static __attribute__((__noreturn__)) void usage(const char *prog)
Packit Service 9fb14c
{
Packit Service 9fb14c
	printf("usage: %s -o <output file> -m <module> [-f <file contexts>]\n",
Packit Service 9fb14c
	       prog);
Packit Service 9fb14c
	printf("Options:\n");
Packit Service 9fb14c
	printf("  -o --outfile		Output file (required)\n");
Packit Service 9fb14c
	printf("  -m --module		Module file (required)\n");
Packit Service 9fb14c
	printf("  -f --fc		File contexts file\n");
Packit Service 9fb14c
	printf("  -s --seuser		Seusers file (only valid in base)\n");
Packit Service 9fb14c
	printf
Packit Service 9fb14c
	    ("  -u --user_extra	user_extra file (only valid in base)\n");
Packit Service 9fb14c
	printf("  -n --nc		Netfilter contexts file\n");
Packit Service 9fb14c
	exit(1);
Packit Service 9fb14c
}
Packit Service 9fb14c
Packit Service 9fb14c
static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
Packit Service 9fb14c
			       const char *mode)
Packit Service 9fb14c
{
Packit Service 9fb14c
	FILE *f;
Packit Service 9fb14c
Packit Service 9fb14c
	if (sepol_policy_file_create(pf)) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Out of memory\n", progname);
Packit Service 9fb14c
		return -1;
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	f = fopen(filename, mode);
Packit Service 9fb14c
	if (!f) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
Packit Service 9fb14c
			strerror(errno), filename);
Packit Service 9fb14c
		return -1;
Packit Service 9fb14c
	}
Packit Service 9fb14c
	sepol_policy_file_set_fp(*pf, f);
Packit Service 9fb14c
	return 0;
Packit Service 9fb14c
}
Packit Service 9fb14c
Packit Service 9fb14c
static int file_to_data(const char *path, char **data, size_t * len)
Packit Service 9fb14c
{
Packit Service 9fb14c
	int fd;
Packit Service 9fb14c
	struct stat sb;
Packit Service 9fb14c
	fd = open(path, O_RDONLY);
Packit Service 9fb14c
	if (fd < 0) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Failed to open %s:  %s\n", progname, path,
Packit Service 9fb14c
			strerror(errno));
Packit Service 9fb14c
		return -1;
Packit Service 9fb14c
	}
Packit Service 9fb14c
	if (fstat(fd, &sb) < 0) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Failed to fstat %s:  %s\n", progname,
Packit Service 9fb14c
			path, strerror(errno));
Packit Service 9fb14c
		goto err;
Packit Service 9fb14c
	}
Packit Service 9fb14c
	if (!sb.st_size) {
Packit Service 9fb14c
		*len = 0;
Packit Service 9fb14c
		close(fd);
Packit Service 9fb14c
		return 0;
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
Packit Service 9fb14c
	if (*data == MAP_FAILED) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Failed to mmap %s:  %s\n", progname, path,
Packit Service 9fb14c
			strerror(errno));
Packit Service 9fb14c
		goto err;
Packit Service 9fb14c
	}
Packit Service 9fb14c
	*len = sb.st_size;
Packit Service 9fb14c
	close(fd);
Packit Service 9fb14c
	return 0;
Packit Service 9fb14c
      err:
Packit Service 9fb14c
	close(fd);
Packit Service 9fb14c
	return -1;
Packit Service 9fb14c
}
Packit Service 9fb14c
Packit Service 9fb14c
int main(int argc, char **argv)
Packit Service 9fb14c
{
Packit Service 9fb14c
	struct sepol_module_package *pkg;
Packit Service 9fb14c
	struct sepol_policy_file *mod, *out;
Packit Service 9fb14c
	char *module = NULL, *file_contexts = NULL, *seusers =
Packit Service 9fb14c
	    NULL, *user_extra = NULL;
Packit Service 9fb14c
	char *fcdata = NULL, *outfile = NULL, *seusersdata =
Packit Service 9fb14c
	    NULL, *user_extradata = NULL;
Packit Service 9fb14c
	char *netfilter_contexts = NULL, *ncdata = NULL;
Packit Service 9fb14c
	size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
Packit Service 9fb14c
	int i;
Packit Service 9fb14c
Packit Service 9fb14c
	static struct option opts[] = {
Packit Service 9fb14c
		{"module", required_argument, NULL, 'm'},
Packit Service 9fb14c
		{"fc", required_argument, NULL, 'f'},
Packit Service 9fb14c
		{"seuser", required_argument, NULL, 's'},
Packit Service 9fb14c
		{"user_extra", required_argument, NULL, 'u'},
Packit Service 9fb14c
		{"nc", required_argument, NULL, 'n'},
Packit Service 9fb14c
		{"outfile", required_argument, NULL, 'o'},
Packit Service 9fb14c
		{"help", 0, NULL, 'h'},
Packit Service 9fb14c
		{NULL, 0, NULL, 0}
Packit Service 9fb14c
	};
Packit Service 9fb14c
Packit Service 9fb14c
	while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
Packit Service 9fb14c
		switch (i) {
Packit Service 9fb14c
		case 'h':
Packit Service 9fb14c
			usage(argv[0]);
Packit Service 9fb14c
			exit(0);
Packit Service 9fb14c
		case 'm':
Packit Service 9fb14c
			if (module) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one module\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			module = strdup(optarg);
Packit Service 9fb14c
			if (!module)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		case 'f':
Packit Service 9fb14c
			if (file_contexts) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one file context file\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			file_contexts = strdup(optarg);
Packit Service 9fb14c
			if (!file_contexts)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		case 'o':
Packit Service 9fb14c
			if (outfile) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one output file\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			outfile = strdup(optarg);
Packit Service 9fb14c
			if (!outfile)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		case 's':
Packit Service 9fb14c
			if (seusers) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one seuser file\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			seusers = strdup(optarg);
Packit Service 9fb14c
			if (!seusers)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		case 'u':
Packit Service 9fb14c
			if (user_extra) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one user_extra file\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			user_extra = strdup(optarg);
Packit Service 9fb14c
			if (!user_extra)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		case 'n':
Packit Service 9fb14c
			if (netfilter_contexts) {
Packit Service 9fb14c
				fprintf(stderr,
Packit Service 9fb14c
					"May not specify more than one netfilter contexts file\n");
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			}
Packit Service 9fb14c
			netfilter_contexts = strdup(optarg);
Packit Service 9fb14c
			if (!netfilter_contexts)
Packit Service 9fb14c
				exit(1);
Packit Service 9fb14c
			break;
Packit Service 9fb14c
		}
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	progname = argv[0];
Packit Service 9fb14c
Packit Service 9fb14c
	if (!module || !outfile) {
Packit Service 9fb14c
		usage(argv[0]);
Packit Service 9fb14c
		exit(0);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (file_contexts) {
Packit Service 9fb14c
		if (file_to_data(file_contexts, &fcdata, &fclen))
Packit Service 9fb14c
			exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (seusers) {
Packit Service 9fb14c
		if (file_to_data(seusers, &seusersdata, &seuserslen))
Packit Service 9fb14c
			exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (user_extra) {
Packit Service 9fb14c
		if (file_to_data(user_extra, &user_extradata, &user_extralen))
Packit Service 9fb14c
			exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (netfilter_contexts) {
Packit Service 9fb14c
		if (file_to_data(netfilter_contexts, &ncdata, &nclen))
Packit Service 9fb14c
			exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (file_to_policy_file(module, &mod, "r"))
Packit Service 9fb14c
		exit(1);
Packit Service 9fb14c
Packit Service 9fb14c
	if (sepol_module_package_create(&pkg)) {
Packit Service 9fb14c
		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
Packit Service 9fb14c
		exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
Packit Service 9fb14c
		fprintf(stderr,
Packit Service 9fb14c
			"%s:  Error while reading policy module from %s\n",
Packit Service 9fb14c
			argv[0], module);
Packit Service 9fb14c
		exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (fclen)
Packit Service 9fb14c
		sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
Packit Service 9fb14c
Packit Service 9fb14c
	if (seuserslen)
Packit Service 9fb14c
		sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
Packit Service 9fb14c
Packit Service 9fb14c
	if (user_extra)
Packit Service 9fb14c
		sepol_module_package_set_user_extra(pkg, user_extradata,
Packit Service 9fb14c
						    user_extralen);
Packit Service 9fb14c
Packit Service 9fb14c
	if (nclen)
Packit Service 9fb14c
		sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
Packit Service 9fb14c
Packit Service 9fb14c
	if (file_to_policy_file(outfile, &out, "w"))
Packit Service 9fb14c
		exit(1);
Packit Service 9fb14c
Packit Service 9fb14c
	if (sepol_module_package_write(pkg, out)) {
Packit Service 9fb14c
		fprintf(stderr,
Packit Service 9fb14c
			"%s:  Error while writing module package to %s\n",
Packit Service 9fb14c
			argv[0], argv[1]);
Packit Service 9fb14c
		exit(1);
Packit Service 9fb14c
	}
Packit Service 9fb14c
Packit Service 9fb14c
	if (fclen)
Packit Service 9fb14c
		munmap(fcdata, fclen);
Packit Service 9fb14c
	if (nclen)
Packit Service 9fb14c
		munmap(ncdata, nclen);
Packit Service 9fb14c
	sepol_policy_file_free(mod);
Packit Service 9fb14c
	sepol_policy_file_free(out);
Packit Service 9fb14c
	sepol_module_package_free(pkg);
Packit Service 9fb14c
	free(file_contexts);
Packit Service 9fb14c
	free(outfile);
Packit Service 9fb14c
	free(module);
Packit Service 9fb14c
	free(seusers);
Packit Service 9fb14c
	free(user_extra);
Packit Service 9fb14c
	exit(0);
Packit Service 9fb14c
}