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. */
13static 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
23int 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