1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <libgen.h>
5 #include <errno.h>
6 #include <selinux/selinux.h>
7 #include <syslog.h>
8 #include <pwd.h>
9 #include <string.h>
10
11 /* Attempt to rollback the transaction. No need to check error
12 codes since this is rolling back something that blew up. */
rollback(int argc,char ** argv)13 static __attribute__ ((__noreturn__)) void rollback(int argc, char **argv)
14 {
15 int i;
16
17 for (i = 1; i < argc; i++)
18 security_set_boolean(argv[i],
19 security_get_boolean_active(argv[i]));
20 exit(1);
21 }
22
main(int argc,char ** argv)23 int main(int argc, char **argv)
24 {
25
26 int rc, i, commit = 0;
27
28 if (is_selinux_enabled() <= 0) {
29 fprintf(stderr, "%s: SELinux is disabled\n", argv[0]);
30 return 1;
31 }
32
33 if (argc < 2) {
34 printf("Usage: %s boolname1 [boolname2 ...]\n",
35 basename(argv[0]));
36 return 1;
37 }
38
39 for (i = 1; i < argc; i++) {
40 printf("%s: ", argv[i]);
41 rc = security_get_boolean_active(argv[i]);
42 switch (rc) {
43 case 1:
44 if (security_set_boolean(argv[i], 0) >= 0) {
45 printf("inactive\n");
46 commit++;
47 } else {
48 printf("%s - rolling back all changes\n",
49 strerror(errno));
50 rollback(i, argv);
51 }
52 break;
53 case 0:
54 if (security_set_boolean(argv[i], 1) >= 0) {
55 printf("active\n");
56 commit++;
57 } else {
58 printf("%s - rolling back all changes\n",
59 strerror(errno));
60 rollback(i, argv);
61 }
62 break;
63 default:
64 if (errno == ENOENT)
65 printf
66 ("Boolean does not exist - rolling back all changes.\n");
67 else
68 printf("%s - rolling back all changes.\n",
69 strerror(errno));
70 rollback(i, argv);
71 break; /* Not reached. */
72 }
73 }
74
75 if (commit > 0) {
76 if (security_commit_booleans() < 0) {
77 printf("Commit failed. (%s) No change to booleans.\n",
78 strerror(errno));
79 } else {
80 /* syslog all the changes */
81 struct passwd *pwd = getpwuid(getuid());
82 for (i = 1; i < argc; i++) {
83 if (pwd && pwd->pw_name)
84 syslog(LOG_NOTICE,
85 "The %s policy boolean was toggled by %s",
86 argv[i], pwd->pw_name);
87 else
88 syslog(LOG_NOTICE,
89 "The %s policy boolean was toggled by uid:%u",
90 argv[i], getuid());
91
92 }
93 return 0;
94 }
95 }
96 return 1;
97 }
98