1/* Authors: Karl MacMillan <kmacmillan@tresys.com> 2 * Joshua Brindle <jbrindle@tresys.com> 3 * 4 * Copyright (C) 2004 Tresys Technology, LLC 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, version 2. 8 */ 9 10#include <sepol/policydb.h> 11#include <sepol/module.h> 12 13#include <getopt.h> 14#include <fcntl.h> 15#include <stdio.h> 16#include <errno.h> 17#include <sys/mman.h> 18#include <sys/types.h> 19#include <sys/stat.h> 20#include <stdlib.h> 21#include <unistd.h> 22#include <string.h> 23 24extern char *optarg; 25extern int optind; 26 27int policyvers = 0; 28 29#define EXPANDPOLICY_VERSION "1.0" 30 31static void usage(char *program_name) 32{ 33 printf("usage: %s [-V -a -c [version]] basemodpkg outputfile\n", 34 program_name); 35 exit(1); 36} 37 38int main(int argc, char **argv) 39{ 40 char *basename, *outname; 41 int ch, ret, show_version = 0, verbose = 0; 42 struct sepol_policy_file *pf; 43 sepol_module_package_t *base; 44 sepol_policydb_t *out, *p; 45 FILE *fp, *outfile; 46 int check_assertions = 1; 47 sepol_handle_t *handle; 48 49 while ((ch = getopt(argc, argv, "c:Vva")) != EOF) { 50 switch (ch) { 51 case 'V': 52 show_version = 1; 53 break; 54 case 'v': 55 verbose = 1; 56 break; 57 case 'c':{ 58 long int n = strtol(optarg, NULL, 10); 59 if (errno) { 60 fprintf(stderr, 61 "%s: Invalid policyvers specified: %s\n", 62 argv[0], optarg); 63 usage(argv[0]); 64 exit(1); 65 } 66 if (n < sepol_policy_kern_vers_min() 67 || n > sepol_policy_kern_vers_max()) { 68 fprintf(stderr, 69 "%s: policyvers value %ld not in range %d-%d\n", 70 argv[0], n, 71 sepol_policy_kern_vers_min(), 72 sepol_policy_kern_vers_max()); 73 usage(argv[0]); 74 exit(1); 75 } 76 policyvers = n; 77 break; 78 } 79 case 'a':{ 80 check_assertions = 0; 81 break; 82 } 83 default: 84 usage(argv[0]); 85 } 86 } 87 88 if (verbose) { 89 if (policyvers) 90 printf("Building version %d policy\n", policyvers); 91 } 92 93 if (show_version) { 94 printf("%s\n", EXPANDPOLICY_VERSION); 95 exit(0); 96 } 97 98 /* check args */ 99 if (argc < 3 || !(optind != (argc - 1))) { 100 fprintf(stderr, 101 "%s: You must provide the base module package and output filename\n", 102 argv[0]); 103 usage(argv[0]); 104 } 105 106 basename = argv[optind++]; 107 outname = argv[optind]; 108 109 handle = sepol_handle_create(); 110 if (!handle) 111 exit(1); 112 113 if (sepol_policy_file_create(&pf)) { 114 fprintf(stderr, "%s: Out of memory\n", argv[0]); 115 exit(1); 116 } 117 118 /* read the base module */ 119 if (sepol_module_package_create(&base)) { 120 fprintf(stderr, "%s: Out of memory\n", argv[0]); 121 exit(1); 122 } 123 fp = fopen(basename, "r"); 124 if (!fp) { 125 fprintf(stderr, "%s: Can't open '%s': %s\n", 126 argv[0], basename, strerror(errno)); 127 exit(1); 128 } 129 sepol_policy_file_set_fp(pf, fp); 130 ret = sepol_module_package_read(base, pf, 0); 131 if (ret) { 132 fprintf(stderr, "%s: Error in reading package from %s\n", 133 argv[0], basename); 134 exit(1); 135 } 136 fclose(fp); 137 138 /* linking the base takes care of enabling optional avrules */ 139 p = sepol_module_package_get_policy(base); 140 if (sepol_link_modules(handle, p, NULL, 0, 0)) { 141 fprintf(stderr, "%s: Error while enabling avrules\n", argv[0]); 142 exit(1); 143 } 144 145 /* create the output policy */ 146 147 if (sepol_policydb_create(&out)) { 148 fprintf(stderr, "%s: Out of memory\n", argv[0]); 149 exit(1); 150 } 151 152 sepol_set_expand_consume_base(handle, 1); 153 154 if (sepol_expand_module(handle, p, out, verbose, check_assertions)) { 155 fprintf(stderr, "%s: Error while expanding policy\n", argv[0]); 156 exit(1); 157 } 158 159 if (policyvers) { 160 if (sepol_policydb_set_vers(out, policyvers)) { 161 fprintf(stderr, "%s: Invalid version %d\n", argv[0], 162 policyvers); 163 exit(1); 164 } 165 } 166 167 sepol_module_package_free(base); 168 169 outfile = fopen(outname, "w"); 170 if (!outfile) { 171 perror(outname); 172 exit(1); 173 } 174 175 sepol_policy_file_set_fp(pf, outfile); 176 ret = sepol_policydb_write(out, pf); 177 if (ret) { 178 fprintf(stderr, 179 "%s: Error while writing expanded policy to %s\n", 180 argv[0], outname); 181 exit(1); 182 } 183 fclose(outfile); 184 sepol_handle_destroy(handle); 185 sepol_policydb_free(out); 186 sepol_policy_file_free(pf); 187 188 return 0; 189} 190