1#include <unistd.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <getopt.h>
5#include <errno.h>
6#include <string.h>
7#include <selinux/selinux.h>
8
9static __attribute__ ((__noreturn__)) void usage(const char *progname)
10{
11	fprintf(stderr, "usage:  %s -a or %s boolean...\n", progname, progname);
12	exit(1);
13}
14
15int main(int argc, char **argv)
16{
17	int i, get_all = 0, rc = 0, active, pending, len = 0, opt;
18	char **names = NULL;
19
20	while ((opt = getopt(argc, argv, "a")) > 0) {
21		switch (opt) {
22		case 'a':
23			if (argc > 2)
24				usage(argv[0]);
25			if (is_selinux_enabled() <= 0) {
26				fprintf(stderr, "%s:  SELinux is disabled\n",
27					argv[0]);
28				return 1;
29			}
30			errno = 0;
31			rc = security_get_boolean_names(&names, &len);
32			if (rc) {
33				fprintf(stderr,
34					"%s:  Unable to get boolean names:  %s\n",
35					argv[0], strerror(errno));
36				return 1;
37			}
38			if (!len) {
39				printf("No booleans\n");
40				return 0;
41			}
42			get_all = 1;
43			break;
44		default:
45			usage(argv[0]);
46		}
47	}
48
49	if (is_selinux_enabled() <= 0) {
50		fprintf(stderr, "%s:  SELinux is disabled\n", argv[0]);
51		return 1;
52	}
53
54	if (!len) {
55		if (argc < 2)
56			usage(argv[0]);
57		len = argc - 1;
58		names = calloc(len, sizeof(char *));
59		if (!names) {
60			fprintf(stderr, "%s:  out of memory\n", argv[0]);
61			return 2;
62		}
63		for (i = 0; i < len; i++) {
64			names[i] = strdup(argv[i + 1]);
65			if (!names[i]) {
66				fprintf(stderr, "%s:  out of memory\n",
67					argv[0]);
68				rc = 2;
69				goto out;
70			}
71		}
72	}
73
74	for (i = 0; i < len; i++) {
75		active = security_get_boolean_active(names[i]);
76		if (active < 0) {
77			if (get_all && errno == EACCES)
78				continue;
79			fprintf(stderr, "Error getting active value for %s\n",
80				names[i]);
81			rc = -1;
82			goto out;
83		}
84		pending = security_get_boolean_pending(names[i]);
85		if (pending < 0) {
86			fprintf(stderr, "Error getting pending value for %s\n",
87				names[i]);
88			rc = -1;
89			goto out;
90		}
91		char *alt_name = selinux_boolean_sub(names[i]);
92		if (! alt_name) {
93			perror("Out of memory\n");
94			rc = -1;
95			goto out;
96		}
97
98		if (pending != active) {
99			printf("%s --> %s pending: %s\n", alt_name,
100			       (active ? "on" : "off"),
101			       (pending ? "on" : "off"));
102		} else {
103			printf("%s --> %s\n", alt_name,
104			       (active ? "on" : "off"));
105		}
106		free(alt_name);
107	}
108
109      out:
110	for (i = 0; i < len; i++)
111		free(names[i]);
112	free(names);
113	return rc;
114}
115