Home | History | Annotate | Download | only in semodule_link
      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 
     11 #include <getopt.h>
     12 #include <fcntl.h>
     13 #include <stdio.h>
     14 #include <errno.h>
     15 #include <sys/mman.h>
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 #include <stdlib.h>
     19 #include <unistd.h>
     20 #include <string.h>
     21 
     22 #define LINKPOLICY_VERSION "1.0"
     23 
     24 char *progname;
     25 extern char *optarg;
     26 extern int optind;
     27 
     28 static void usage(char *program_name)
     29 {
     30 	printf("usage: %s [-Vv] [-o outfile] basemodpkg modpkg1 [modpkg2]...\n",
     31 	       program_name);
     32 	exit(1);
     33 }
     34 
     35 static sepol_module_package_t *load_module(char *filename)
     36 {
     37 	int ret;
     38 	FILE *fp = NULL;
     39 	struct sepol_policy_file *pf = NULL;
     40 	sepol_module_package_t *p = NULL;
     41 
     42 	if (sepol_module_package_create(&p)) {
     43 		fprintf(stderr, "%s:  Out of memory\n", progname);
     44 		goto bad;
     45 	}
     46 	if (sepol_policy_file_create(&pf)) {
     47 		fprintf(stderr, "%s:  Out of memory\n", progname);
     48 		goto bad;
     49 	}
     50 	fp = fopen(filename, "r");
     51 	if (!fp) {
     52 		fprintf(stderr, "%s:  Could not open package %s:  %s", progname,
     53 			filename, strerror(errno));
     54 		goto bad;
     55 	}
     56 	sepol_policy_file_set_fp(pf, fp);
     57 
     58 	printf("%s:  loading package from file %s\n", progname, filename);
     59 
     60 	ret = sepol_module_package_read(p, pf, 0);
     61 	if (ret) {
     62 		fprintf(stderr, "%s:  Error while reading package from %s\n",
     63 			progname, filename);
     64 		goto bad;
     65 	}
     66 	fclose(fp);
     67 	sepol_policy_file_free(pf);
     68 	return p;
     69       bad:
     70 	sepol_module_package_free(p);
     71 	sepol_policy_file_free(pf);
     72 	if (fp)
     73 		fclose(fp);
     74 	return NULL;
     75 }
     76 
     77 int main(int argc, char **argv)
     78 {
     79 	int ch, i, show_version = 0, verbose = 0, num_mods;
     80 	char *basename, *outname = NULL;
     81 	sepol_module_package_t *base, **mods;
     82 	FILE *outfile;
     83 	struct sepol_policy_file *pf;
     84 
     85 	progname = argv[0];
     86 
     87 	while ((ch = getopt(argc, argv, "o:Vv")) != EOF) {
     88 		switch (ch) {
     89 		case 'V':
     90 			show_version = 1;
     91 			break;
     92 		case 'v':
     93 			verbose = 1;
     94 			break;
     95 		case 'o':
     96 			outname = optarg;
     97 			break;
     98 		default:
     99 			usage(argv[0]);
    100 		}
    101 	}
    102 
    103 	if (show_version) {
    104 		printf("%s\n", LINKPOLICY_VERSION);
    105 		exit(0);
    106 	}
    107 
    108 	/* check args */
    109 	if (argc < 3 || !(optind != (argc - 1))) {
    110 		fprintf(stderr,
    111 			"%s:  You must provide the base module package and at least one other module package\n",
    112 			argv[0]);
    113 		usage(argv[0]);
    114 	}
    115 
    116 	basename = argv[optind++];
    117 	base = load_module(basename);
    118 	if (!base) {
    119 		fprintf(stderr,
    120 			"%s:  Could not load base module from file %s\n",
    121 			argv[0], basename);
    122 		exit(1);
    123 	}
    124 
    125 	num_mods = argc - optind;
    126 	mods =
    127 	    (sepol_module_package_t **) malloc(sizeof(sepol_module_package_t *)
    128 					       * num_mods);
    129 	if (!mods) {
    130 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
    131 		exit(1);
    132 	}
    133 	memset(mods, 0, sizeof(sepol_module_package_t *) * num_mods);
    134 
    135 	for (i = 0; optind < argc; optind++, i++) {
    136 		mods[i] = load_module(argv[optind]);
    137 		if (!mods[i]) {
    138 			fprintf(stderr,
    139 				"%s:  Could not load module from file %s\n",
    140 				argv[0], argv[optind]);
    141 			exit(1);
    142 		}
    143 	}
    144 
    145 	if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
    146 		fprintf(stderr, "%s:  Error while linking packages\n", argv[0]);
    147 		exit(1);
    148 	}
    149 
    150 	if (outname) {
    151 		outfile = fopen(outname, "w");
    152 		if (!outfile) {
    153 			perror(outname);
    154 			exit(1);
    155 		}
    156 
    157 		if (sepol_policy_file_create(&pf)) {
    158 			fprintf(stderr, "%s:  Out of memory\n", argv[0]);
    159 			exit(1);
    160 		}
    161 		sepol_policy_file_set_fp(pf, outfile);
    162 		if (sepol_module_package_write(base, pf)) {
    163 			fprintf(stderr, "%s:  Error writing linked package.\n",
    164 				argv[0]);
    165 			exit(1);
    166 		}
    167 		sepol_policy_file_free(pf);
    168 		fclose(outfile);
    169 	}
    170 
    171 	sepol_module_package_free(base);
    172 	for (i = 0; i < num_mods; i++)
    173 		sepol_module_package_free(mods[i]);
    174 	free(mods);
    175 	exit(0);
    176 }
    177