1 /* Authors: Karl MacMillan <[email protected]>
2 * Joshua Brindle <[email protected]>
3 * Jason Tang <[email protected]>
4 *
5 * Copyright (C) 2004-2005 Tresys Technology, LLC
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10
11 #include <fcntl.h>
12 #include <getopt.h>
13 #include <signal.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <libgen.h>
23 #include <limits.h>
24
25 #include <sepol/cil/cil.h>
26 #include <semanage/modules.h>
27
28 enum client_modes {
29 NO_MODE, INSTALL_M, REMOVE_M, EXTRACT_M, CIL_M, HLL_M,
30 LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
31 };
32 /* list of modes in which one ought to commit afterwards */
33 static const int do_commit[] = {
34 0, 1, 1, 0, 0, 0,
35 0, 0, 0, 1, 1,
36 };
37
38 struct command {
39 enum client_modes mode;
40 char *arg;
41 };
42 static struct command *commands = NULL;
43 static int num_commands = 0;
44
45 /* options given on command line */
46 static int verbose;
47 static int reload;
48 static int no_reload;
49 static int build;
50 static int check_ext_changes;
51 static int disable_dontaudit;
52 static int preserve_tunables;
53 static int ignore_module_cache;
54 static uint16_t priority;
55 static int priority_set = 0;
56
57 static semanage_handle_t *sh = NULL;
58 static char *store;
59 static char *store_root;
60 int extract_cil = 0;
61 static int checksum = 0;
62
63 extern char *optarg;
64 extern int optind;
65
cleanup(void)66 static void cleanup(void)
67 {
68 while (--num_commands >= 0) {
69 free(commands[num_commands].arg);
70 }
71 free(commands);
72 }
73
74 /* Signal handlers. */
handle_signal(int sig_num)75 static void handle_signal(int sig_num)
76 {
77 if (sig_num == SIGINT || sig_num == SIGQUIT || sig_num == SIGTERM) {
78 /* catch these signals, and then drop them */
79 }
80 }
81
set_store(char * storename)82 static void set_store(char *storename)
83 {
84 /* For now this only supports a store name, later on this
85 * should support an address for a remote connection */
86
87 if ((store = strdup(storename)) == NULL) {
88 fprintf(stderr, "Out of memory!\n");
89 goto bad;
90 }
91
92 return;
93
94 bad:
95 cleanup();
96 exit(1);
97 }
98
set_store_root(char * path)99 static void set_store_root(char *path)
100 {
101 if ((store_root = strdup(path)) == NULL) {
102 fprintf(stderr, "Out of memory!\n");
103 goto bad;
104 }
105
106 return;
107
108 bad:
109 cleanup();
110 exit(1);
111 }
112
113 /* Establish signal handlers for the process. */
create_signal_handlers(void)114 static void create_signal_handlers(void)
115 {
116 if (signal(SIGINT, handle_signal) == SIG_ERR ||
117 signal(SIGQUIT, handle_signal) == SIG_ERR ||
118 signal(SIGTERM, handle_signal) == SIG_ERR) {
119 fprintf(stderr, "Could not set up signal handler.\n");
120 exit(255);
121 }
122 }
123
usage(char * progname)124 static void usage(char *progname)
125 {
126 printf("usage: %s [option]... MODE...\n", progname);
127 printf("Manage SELinux policy modules.\n");
128 printf("MODES:\n");
129 printf(" -R, --reload reload policy\n");
130 printf(" -B, --build build and reload policy\n");
131 printf(" -D,--disable_dontaudit Remove dontaudits from policy\n");
132 printf(" -i,--install=MODULE_PKG install a new module\n");
133 printf(" -r,--remove=MODULE_NAME remove existing module at desired priority\n");
134 printf(" -l[KIND],--list-modules[=KIND] display list of installed modules\n");
135 printf(" KIND: standard list highest priority, enabled modules\n");
136 printf(" full list all modules\n");
137 printf(" -X,--priority=PRIORITY set priority for following operations (1-999)\n");
138 printf(" -e,--enable=MODULE_NAME enable module\n");
139 printf(" -d,--disable=MODULE_NAME disable module\n");
140 printf(" -E,--extract=MODULE_NAME extract module\n");
141 printf("Options:\n");
142 printf(" -s,--store name of the store to operate on\n");
143 printf(" -N,-n,--noreload do not reload policy after commit\n");
144 printf(" -h,--help print this message and quit\n");
145 printf(" -v,--verbose be verbose\n");
146 printf(" -P,--preserve_tunables Preserve tunables in policy\n");
147 printf(" -C,--ignore-module-cache Rebuild CIL modules compiled from HLL files\n");
148 printf(" -p,--path use an alternate path for the policy root\n");
149 printf(" -S,--store-path use an alternate path for the policy store root\n");
150 printf(" -c, --cil extract module as cil. This only affects module extraction.\n");
151 printf(" -H, --hll extract module as hll. This only affects module extraction.\n");
152 printf(" -m, --checksum print module checksum (SHA256).\n");
153 printf(" --refresh like --build, but reuses existing linked policy if no\n"
154 " changes to module files are detected (via checksum)\n");
155 printf("Deprecated options:\n");
156 printf(" -b,--base same as --install\n");
157 printf(" --rebuild-if-modules-changed\n"
158 " same as --refresh\n");
159 }
160
161 /* Sets the global mode variable to new_mode, but only if no other
162 * mode has been given. */
set_mode(enum client_modes new_mode,char * arg)163 static void set_mode(enum client_modes new_mode, char *arg)
164 {
165 struct command *c;
166 char *s;
167 if ((c = realloc(commands, sizeof(*c) * (num_commands + 1))) == NULL) {
168 fprintf(stderr, "Out of memory!\n");
169 cleanup();
170 exit(1);
171 }
172 commands = c;
173 commands[num_commands].mode = new_mode;
174 commands[num_commands].arg = NULL;
175 num_commands++;
176 if (arg != NULL) {
177 if ((s = strdup(arg)) == NULL) {
178 fprintf(stderr, "Out of memory!\n");
179 cleanup();
180 exit(1);
181 }
182 commands[num_commands - 1].arg = s;
183 }
184 }
185
186 /* Parse command line and set global options. */
parse_command_line(int argc,char ** argv)187 static void parse_command_line(int argc, char **argv)
188 {
189 static struct option opts[] = {
190 {"rebuild-if-modules-changed", 0, NULL, '\0'},
191 {"refresh", 0, NULL, '\0'},
192 {"store", required_argument, NULL, 's'},
193 {"base", required_argument, NULL, 'b'},
194 {"help", 0, NULL, 'h'},
195 {"install", required_argument, NULL, 'i'},
196 {"extract", required_argument, NULL, 'E'},
197 {"cil", 0, NULL, 'c'},
198 {"hll", 0, NULL, 'H'},
199 {"list-modules", optional_argument, NULL, 'l'},
200 {"verbose", 0, NULL, 'v'},
201 {"remove", required_argument, NULL, 'r'},
202 {"upgrade", required_argument, NULL, 'u'},
203 {"reload", 0, NULL, 'R'},
204 {"noreload", 0, NULL, 'n'},
205 {"build", 0, NULL, 'B'},
206 {"disable_dontaudit", 0, NULL, 'D'},
207 {"preserve_tunables", 0, NULL, 'P'},
208 {"ignore-module-cache", 0, NULL, 'C'},
209 {"priority", required_argument, NULL, 'X'},
210 {"enable", required_argument, NULL, 'e'},
211 {"disable", required_argument, NULL, 'd'},
212 {"path", required_argument, NULL, 'p'},
213 {"store-path", required_argument, NULL, 'S'},
214 {"checksum", 0, NULL, 'm'},
215 {NULL, 0, NULL, 0}
216 };
217 int extract_selected = 0;
218 int cil_hll_set = 0;
219 int i, longind;
220 verbose = 0;
221 reload = 0;
222 no_reload = 0;
223 check_ext_changes = 0;
224 priority = 400;
225 while ((i =
226 getopt_long(argc, argv, "s:b:hi:l::vr:u:RnNBDCPX:e:d:p:S:E:cHm",
227 opts, &longind)) != -1) {
228 switch (i) {
229 case '\0':
230 switch(longind) {
231 case 0: /* --rebuild-if-modules-changed */
232 fprintf(stderr, "The --rebuild-if-modules-changed option is deprecated. Use --refresh instead.\n");
233 /* fallthrough */
234 case 1: /* --refresh */
235 check_ext_changes = 1;
236 break;
237 default:
238 usage(argv[0]);
239 exit(1);
240 }
241 break;
242 case 'b':
243 fprintf(stderr, "The --base option is deprecated. Use --install instead.\n");
244 set_mode(INSTALL_M, optarg);
245 break;
246 case 'h':
247 usage(argv[0]);
248 exit(0);
249 case 'i':
250 set_mode(INSTALL_M, optarg);
251 break;
252 case 'E':
253 set_mode(EXTRACT_M, optarg);
254 extract_selected = 1;
255 break;
256 case 'c':
257 set_mode(CIL_M, NULL);
258 cil_hll_set = 1;
259 break;
260 case 'H':
261 set_mode(HLL_M, NULL);
262 cil_hll_set = 1;
263 break;
264 case 'l':
265 set_mode(LIST_M, optarg);
266 break;
267 case 'v':
268 verbose++;
269 break;
270 case 'r':
271 set_mode(REMOVE_M, optarg);
272 break;
273 case 'u':
274 fprintf(stderr, "The --upgrade option is deprecated. Use --install instead.\n");
275 set_mode(INSTALL_M, optarg);
276 break;
277 case 's':
278 set_store(optarg);
279 break;
280 case 'p':
281 semanage_set_root(optarg);
282 break;
283 case 'S':
284 set_store_root(optarg);
285 break;
286 case 'R':
287 reload = 1;
288 break;
289 case 'n':
290 no_reload = 1;
291 break;
292 case 'N':
293 no_reload = 1;
294 break;
295 case 'B':
296 build = 1;
297 break;
298 case 'D':
299 disable_dontaudit = 1;
300 break;
301 case 'P':
302 preserve_tunables = 1;
303 break;
304 case 'C':
305 ignore_module_cache = 1;
306 break;
307 case 'X':
308 set_mode(PRIORITY_M, optarg);
309 break;
310 case 'e':
311 set_mode(ENABLE_M, optarg);
312 break;
313 case 'd':
314 set_mode(DISABLE_M, optarg);
315 break;
316 case 'm':
317 checksum = 1;
318 break;
319 case '?':
320 default:{
321 usage(argv[0]);
322 exit(1);
323 }
324 }
325 }
326 if ((build || reload || check_ext_changes) && num_commands) {
327 fprintf(stderr,
328 "build or reload should not be used with other commands\n");
329 usage(argv[0]);
330 exit(1);
331 }
332 if (num_commands == 0 && reload == 0 && build == 0 && check_ext_changes == 0) {
333 fprintf(stderr, "At least one mode must be specified.\n");
334 usage(argv[0]);
335 exit(1);
336 }
337 if (extract_selected == 0 && cil_hll_set == 1) {
338 fprintf(stderr, "--cil and --hll require a module to export with the --extract option.\n");
339 usage(argv[0]);
340 exit(1);
341 }
342
343 if (optind < argc) {
344 int mode = commands ? (int) commands[num_commands - 1].mode : -1;
345 /* if -i/u/r/E was the last command treat any remaining
346 * arguments as args. Will allow 'semodule -i *.pp' to
347 * work as expected.
348 */
349
350 switch (mode) {
351 case INSTALL_M:
352 case REMOVE_M:
353 case EXTRACT_M:
354 case ENABLE_M:
355 case DISABLE_M:
356 while (optind < argc)
357 set_mode(mode, argv[optind++]);
358 break;
359 default:
360 fprintf(stderr, "unknown additional arguments:\n");
361 while (optind < argc)
362 fprintf(stderr, " %s", argv[optind++]);
363 fprintf(stderr, "\n\n");
364 usage(argv[0]);
365 exit(1);
366 }
367 }
368 }
369
370 /* Get module checksum */
hash_module_data(const char * module_name,const int prio)371 static char *hash_module_data(const char *module_name, const int prio) {
372 semanage_module_key_t *modkey = NULL;
373 char *hash_str = NULL;
374 void *hash = NULL;
375 size_t hash_len = 0;
376 int result;
377
378 result = semanage_module_key_create(sh, &modkey);
379 if (result != 0) {
380 goto cleanup;
381 }
382
383 result = semanage_module_key_set_name(sh, modkey, module_name);
384 if (result != 0) {
385 goto cleanup;
386 }
387
388 result = semanage_module_key_set_priority(sh, modkey, prio);
389 if (result != 0) {
390 goto cleanup;
391 }
392
393 result = semanage_module_compute_checksum(sh, modkey, 1, &hash_str,
394 &hash_len);
395 if (result != 0) {
396 goto cleanup;
397 }
398
399 cleanup:
400 free(hash);
401 semanage_module_key_destroy(sh, modkey);
402 free(modkey);
403 return hash_str;
404 }
405
main(int argc,char * argv[])406 int main(int argc, char *argv[])
407 {
408 int i, commit = 0;
409 int result;
410 int status = EXIT_FAILURE;
411 const char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" };
412 create_signal_handlers();
413 if (strcmp(basename(argv[0]), "genhomedircon") == 0) {
414 argc = 3;
415 argv = (char **)genhomedirconargv;
416 }
417 parse_command_line(argc, argv);
418
419 cil_set_log_level(CIL_ERR + verbose);
420
421 if (build || check_ext_changes)
422 commit = 1;
423
424 sh = semanage_handle_create();
425 if (!sh) {
426 fprintf(stderr, "%s: Could not create semanage handle\n",
427 argv[0]);
428 goto cleanup_nohandle;
429 }
430
431 if (store) {
432 /* Set the store we want to connect to, before connecting.
433 * this will always set a direct connection now, an additional
434 * option will need to be used later to specify a policy server
435 * location */
436 semanage_select_store(sh, store, SEMANAGE_CON_DIRECT);
437 }
438
439 if (store_root) {
440 semanage_set_store_root(sh, store_root);
441 }
442
443 /* create store if necessary, for bootstrapping */
444 semanage_set_create_store(sh, 1);
445
446 if ((result = semanage_connect(sh)) < 0) {
447 fprintf(stderr, "%s: Could not connect to policy handler\n",
448 argv[0]);
449 goto cleanup;
450 }
451
452 if (reload) {
453 if ((result = semanage_reload_policy(sh)) < 0) {
454 fprintf(stderr, "%s: Could not reload policy\n",
455 argv[0]);
456 goto cleanup;
457 }
458 }
459
460 if (build || check_ext_changes) {
461 if ((result = semanage_begin_transaction(sh)) < 0) {
462 fprintf(stderr, "%s: Could not begin transaction: %s\n",
463 argv[0], errno ? strerror(errno) : "");
464 goto cleanup;
465 }
466 }
467
468 if ((result = semanage_set_default_priority(sh, priority)) != 0) {
469 fprintf(stderr,
470 "%s: Invalid priority %d (needs to be between 1 and 999)\n",
471 argv[0],
472 priority);
473 goto cleanup;
474 }
475
476 for (i = 0; i < num_commands; i++) {
477 enum client_modes mode = commands[i].mode;
478 char *mode_arg = commands[i].arg;
479
480 switch (mode) {
481 case INSTALL_M:{
482 if (verbose) {
483 printf
484 ("Attempting to install module '%s':\n",
485 mode_arg);
486 }
487 result =
488 semanage_module_install_file(sh, mode_arg);
489 break;
490 }
491 case EXTRACT_M:{
492 semanage_module_info_t *extract_info = NULL;
493 semanage_module_key_t *modkey = NULL;
494 uint16_t curr_priority;
495 void *data = NULL;
496 size_t data_len = 0;
497 char output_path[PATH_MAX];
498 const char *output_name = NULL;
499 const char *lang_ext = NULL;
500 int rlen;
501 FILE *output_fd = NULL;
502
503 result = semanage_module_key_create(sh, &modkey);
504 if (result != 0) {
505 goto cleanup_extract;
506 }
507
508 result = semanage_module_key_set_name(sh, modkey, mode_arg);
509 if (result != 0) {
510 goto cleanup_extract;
511 }
512
513 if (priority_set == 0) {
514 result = semanage_module_get_module_info(sh, modkey, &extract_info);
515 if (result != 0) {
516 goto cleanup_extract;
517 }
518
519 semanage_module_info_get_priority(sh, extract_info, &curr_priority);
520 printf("Extracting at highest existing priority '%d'.\n", curr_priority);
521 priority = curr_priority;
522 }
523
524 result = semanage_module_key_set_priority(sh, modkey, priority);
525 if (result != 0) {
526 goto cleanup_extract;
527 }
528
529 if (verbose) {
530 printf
531 ("Attempting to extract module '%s':\n",
532 mode_arg);
533 }
534 result = semanage_module_extract(sh, modkey, extract_cil, &data, &data_len, &extract_info);
535 if (result != 0) {
536 goto cleanup_extract;
537 }
538
539 if (extract_cil) {
540 lang_ext = "cil";
541 } else {
542 result = semanage_module_info_get_lang_ext(sh, extract_info, &lang_ext);
543 if (result != 0) {
544 goto cleanup_extract;
545 }
546 }
547
548 result = semanage_module_info_get_name(sh, extract_info, &output_name);
549 if (result != 0) {
550 goto cleanup_extract;
551 }
552
553 rlen = snprintf(output_path, PATH_MAX, "%s.%s", output_name, lang_ext);
554 if (rlen < 0 || rlen >= PATH_MAX) {
555 fprintf(stderr, "%s: Failed to generate output path.\n", argv[0]);
556 result = -1;
557 goto cleanup_extract;
558 }
559
560 output_fd = fopen(output_path, "wx");
561 if (output_fd == NULL) {
562 if (errno == EEXIST)
563 fprintf(stderr, "%s: %s is already extracted with extension %s.\n", argv[0], mode_arg, lang_ext);
564 else
565 fprintf(stderr, "%s: Unable to open %s: %s\n", argv[0], output_path, strerror(errno));
566 result = -1;
567 goto cleanup_extract;
568 }
569
570 if (fwrite(data, 1, data_len, output_fd) < data_len) {
571 fprintf(stderr, "%s: Unable to write to %s\n", argv[0], output_path);
572 result = -1;
573 goto cleanup_extract;
574 }
575 cleanup_extract:
576 if (output_fd != NULL) {
577 fclose(output_fd);
578 }
579 if (data_len > 0) {
580 munmap(data, data_len);
581 }
582 semanage_module_info_destroy(sh, extract_info);
583 free(extract_info);
584 semanage_module_key_destroy(sh, modkey);
585 free(modkey);
586 break;
587 }
588 case CIL_M:
589 extract_cil = 1;
590 break;
591 case HLL_M:
592 extract_cil = 0;
593 break;
594 case REMOVE_M:{
595 if (verbose) {
596 printf
597 ("Attempting to remove module '%s':\n",
598 mode_arg);
599 }
600 result = semanage_module_remove(sh, mode_arg);
601 if ( result == -2 ) {
602 continue;
603 }
604 break;
605 }
606 case LIST_M:{
607 semanage_module_info_t *modinfos = NULL;
608 int modinfos_len = 0;
609 semanage_module_info_t *m = NULL;
610 int j = 0;
611 char *module_checksum = NULL;
612 uint16_t pri = 0;
613
614 if (verbose) {
615 printf
616 ("Attempting to list active modules:\n");
617 }
618
619 if (mode_arg == NULL || strcmp(mode_arg, "standard") == 0) {
620 result = semanage_module_list(sh,
621 &modinfos,
622 &modinfos_len);
623 if (result < 0) goto cleanup_list;
624
625 if (modinfos_len == 0) {
626 printf("No modules.\n");
627 }
628
629 const char *name = NULL;
630
631 for (j = 0; j < modinfos_len; j++) {
632 m = semanage_module_list_nth(modinfos, j);
633
634 result = semanage_module_info_get_name(sh, m, &name);
635 if (result != 0) goto cleanup_list;
636
637 result = semanage_module_info_get_priority(sh, m, &pri);
638 if (result != 0) goto cleanup_list;
639
640 printf("%s", name);
641 if (checksum) {
642 module_checksum = hash_module_data(name, pri);
643 if (module_checksum) {
644 printf(" %s", module_checksum);
645 free(module_checksum);
646 }
647 }
648 printf("\n");
649 }
650 }
651 else if (strcmp(mode_arg, "full") == 0) {
652 /* get the modules */
653 result = semanage_module_list_all(sh,
654 &modinfos,
655 &modinfos_len);
656 if (result != 0) goto cleanup_list;
657
658 if (modinfos_len == 0) {
659 printf("No modules.\n");
660 }
661
662 /* calculate column widths */
663 size_t column[5] = { 0, 0, 0, 0, 0 };
664
665 /* fixed width columns */
666 column[0] = sizeof("000") - 1;
667 column[3] = sizeof("disabled") - 1;
668
669 result = semanage_module_compute_checksum(sh, NULL, 0, NULL,
670 &column[4]);
671 if (result != 0) goto cleanup_list;
672
673 /* variable width columns */
674 const char *tmp = NULL;
675 size_t size;
676 for (j = 0; j < modinfos_len; j++) {
677 m = semanage_module_list_nth(modinfos, j);
678
679 result = semanage_module_info_get_name(sh, m, &tmp);
680 if (result != 0) goto cleanup_list;
681
682 size = strlen(tmp);
683 if (size > column[1]) column[1] = size;
684
685 result = semanage_module_info_get_lang_ext(sh, m, &tmp);
686 if (result != 0) goto cleanup_list;
687
688 size = strlen(tmp);
689 if (size > column[2]) column[2] = size;
690 }
691
692 /* print out each module */
693 for (j = 0; j < modinfos_len; j++) {
694 const char *name = NULL;
695 int enabled = 0;
696 const char *lang_ext = NULL;
697
698 m = semanage_module_list_nth(modinfos, j);
699
700 result = semanage_module_info_get_priority(sh, m, &pri);
701 if (result != 0) goto cleanup_list;
702
703 result = semanage_module_info_get_name(sh, m, &name);
704 if (result != 0) goto cleanup_list;
705
706 result = semanage_module_info_get_enabled(sh, m, &enabled);
707 if (result != 0) goto cleanup_list;
708
709 result = semanage_module_info_get_lang_ext(sh, m, &lang_ext);
710 if (result != 0) goto cleanup_list;
711
712 printf("%0*u %-*s %-*s %-*s",
713 (int)column[0], pri,
714 (int)column[1], name,
715 (int)column[2], lang_ext,
716 (int)column[3], enabled ? "" : "disabled");
717 if (checksum) {
718 module_checksum = hash_module_data(name, pri);
719 if (module_checksum) {
720 printf(" %-*s", (int)column[4], module_checksum);
721 free(module_checksum);
722 }
723 }
724 printf("\n");
725
726 }
727 }
728 else {
729 result = -1;
730 }
731
732 cleanup_list:
733 for (j = 0; j < modinfos_len; j++) {
734 m = semanage_module_list_nth(modinfos, j);
735 semanage_module_info_destroy(sh, m);
736 }
737
738 free(modinfos);
739
740 break;
741 }
742 case PRIORITY_M:{
743 char *endptr = NULL;
744 priority = (uint16_t)strtoul(mode_arg, &endptr, 10);
745 priority_set = 1;
746
747 if ((result = semanage_set_default_priority(sh, priority)) != 0) {
748 fprintf(stderr,
749 "%s: Invalid priority %d (needs to be between 1 and 999)\n",
750 argv[0],
751 priority);
752 goto cleanup;
753 }
754
755 break;
756 }
757 case ENABLE_M:{
758 if (verbose) {
759 printf
760 ("Attempting to enable module '%s':\n",
761 mode_arg);
762 }
763
764 semanage_module_key_t *modkey = NULL;
765
766 result = semanage_module_key_create(sh, &modkey);
767 if (result != 0) goto cleanup_enable;
768
769 result = semanage_module_key_set_name(sh, modkey, mode_arg);
770 if (result != 0) goto cleanup_enable;
771
772 result = semanage_module_set_enabled(sh, modkey, 1);
773 if (result != 0) goto cleanup_enable;
774
775 cleanup_enable:
776 semanage_module_key_destroy(sh, modkey);
777 free(modkey);
778
779 break;
780 }
781 case DISABLE_M:{
782 if (verbose) {
783 printf
784 ("Attempting to disable module '%s':\n",
785 mode_arg);
786 }
787
788 semanage_module_key_t *modkey = NULL;
789
790 result = semanage_module_key_create(sh, &modkey);
791 if (result != 0) goto cleanup_disable;
792
793 result = semanage_module_key_set_name(sh, modkey, mode_arg);
794 if (result != 0) goto cleanup_disable;
795
796 result = semanage_module_set_enabled(sh, modkey, 0);
797 if (result != 0) goto cleanup_disable;
798
799 cleanup_disable:
800 semanage_module_key_destroy(sh, modkey);
801 free(modkey);
802
803 break;
804 }
805 default:{
806 fprintf(stderr,
807 "%s: Unknown mode specified.\n",
808 argv[0]);
809 usage(argv[0]);
810 goto cleanup;
811 }
812 }
813 commit += do_commit[mode];
814 if (result < 0) {
815 fprintf(stderr, "%s: Failed on %s!\n", argv[0],
816 mode_arg ? : "list");
817 goto cleanup;
818 } else if (verbose) {
819 printf("Ok: return value of %d.\n", result);
820 }
821 }
822
823 if (commit) {
824 if (verbose)
825 printf("Committing changes:\n");
826 if (no_reload)
827 semanage_set_reload(sh, 0);
828 if (build)
829 semanage_set_rebuild(sh, 1);
830 if (check_ext_changes)
831 semanage_set_check_ext_changes(sh, 1);
832 if (disable_dontaudit)
833 semanage_set_disable_dontaudit(sh, 1);
834 else if (build)
835 semanage_set_disable_dontaudit(sh, 0);
836 if (preserve_tunables)
837 semanage_set_preserve_tunables(sh, 1);
838 if (ignore_module_cache)
839 semanage_set_ignore_module_cache(sh, 1);
840
841 result = semanage_commit(sh);
842 }
843
844 if (result < 0) {
845 fprintf(stderr, "%s: Failed!\n", argv[0]);
846 goto cleanup;
847 } else if (commit && verbose) {
848 printf("Ok: transaction number %d.\n", result);
849 }
850
851 if (semanage_disconnect(sh) < 0) {
852 fprintf(stderr, "%s: Error disconnecting\n", argv[0]);
853 goto cleanup;
854 }
855 status = EXIT_SUCCESS;
856
857 cleanup:
858 if (semanage_is_connected(sh)) {
859 if (semanage_disconnect(sh) < 0) {
860 fprintf(stderr, "%s: Error disconnecting\n", argv[0]);
861 }
862 }
863 semanage_handle_destroy(sh);
864
865 cleanup_nohandle:
866 cleanup();
867 exit(status);
868 }
869