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 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