Fix forgotten license comments
[platform/upstream/busybox.git] / selinux / sestatus.c
1 /*
2  * sestatus -- displays the status of SELinux
3  *
4  * Ported to busybox: KaiGai Kohei <kaigai@ak.jp.nec.com>
5  *
6  * Copyright (C) KaiGai Kohei <kaigai@ak.jp.nec.com>
7  *
8  * Licensed under GPLv2, see file LICENSE in this tarball for details.
9  */
10
11 #include "libbb.h"
12
13 extern char *selinux_mnt;
14
15 #define OPT_VERBOSE     (1 << 0)
16 #define OPT_BOOLEAN     (1 << 1)
17
18 #define COL_FMT         "%-31s "
19
20 static void display_boolean(void)
21 {
22         char **bools;
23         int i, active, pending, nbool;
24
25         if (security_get_boolean_names(&bools, &nbool) < 0)
26                 return;
27
28         puts("\nPolicy booleans:");
29
30         for (i = 0; i < nbool; i++) {
31                 active = security_get_boolean_active(bools[i]);
32                 if (active < 0)
33                         goto skip;
34                 pending = security_get_boolean_pending(bools[i]);
35                 if (pending < 0)
36                         goto skip;
37                 printf(COL_FMT "%s",
38                        bools[i], active == 0 ? "off" : "on");
39                 if (active != pending)
40                         printf(" (%sactivate pending)", pending == 0 ? "in" : "");
41                 bb_putchar('\n');
42  skip:
43                 if (ENABLE_FEATURE_CLEAN_UP)
44                         free(bools[i]);
45         }
46         if (ENABLE_FEATURE_CLEAN_UP)
47                 free(bools);
48 }
49
50 static void read_config(char **pc, int npc, char **fc, int nfc)
51 {
52         char *buf;
53         parser_t *parser;
54         int pc_ofs = 0, fc_ofs = 0, section = -1;
55
56         pc[0] = fc[0] = NULL;
57
58         parser = config_open("/etc/sestatus.conf");
59         while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) {
60                 if (strcmp(buf, "[process]") == 0) {
61                         section = 1;
62                 } else if (strcmp(buf, "[files]") == 0) {
63                         section = 2;
64                 } else {
65                         if (section == 1 && pc_ofs < npc -1) {
66                                 pc[pc_ofs++] = xstrdup(buf);
67                                 pc[pc_ofs] = NULL;
68                         } else if (section == 2 && fc_ofs < nfc - 1) {
69                                 fc[fc_ofs++] = xstrdup(buf);
70                                 fc[fc_ofs] = NULL;
71                         }
72                 }
73         }
74         config_close(parser);
75 }
76
77 static void display_verbose(void)
78 {
79         security_context_t con, _con;
80         char *fc[50], *pc[50], *cterm;
81         pid_t *pidList;
82         int i;
83
84         read_config(pc, ARRAY_SIZE(pc), fc, ARRAY_SIZE(fc));
85
86         /* process contexts */
87         puts("\nProcess contexts:");
88
89         /* current context */
90         if (getcon(&con) == 0) {
91                 printf(COL_FMT "%s\n", "Current context:", con);
92                 if (ENABLE_FEATURE_CLEAN_UP)
93                         freecon(con);
94         }
95         /* /sbin/init context */
96         if (getpidcon(1, &con) == 0) {
97                 printf(COL_FMT "%s\n", "Init context:", con);
98                 if (ENABLE_FEATURE_CLEAN_UP)
99                         freecon(con);
100         }
101
102         /* [process] context */
103         for (i = 0; pc[i] != NULL; i++) {
104                 pidList = find_pid_by_name(bb_basename(pc[i]));
105                 if (pidList[0] > 0 && getpidcon(pidList[0], &con) == 0) {
106                         printf(COL_FMT "%s\n", pc[i], con);
107                         if (ENABLE_FEATURE_CLEAN_UP)
108                                 freecon(con);
109                 }
110                 if (ENABLE_FEATURE_CLEAN_UP)
111                         free(pidList);
112         }
113
114         /* files contexts */
115         puts("\nFile contexts:");
116
117         cterm = ttyname(0);
118         puts(cterm);
119         if (cterm && lgetfilecon(cterm, &con) >= 0) {
120                 printf(COL_FMT "%s\n", "Controlling term:", con);
121                 if (ENABLE_FEATURE_CLEAN_UP)
122                         freecon(con);
123         }
124
125         for (i=0; fc[i] != NULL; i++) {
126                 struct stat stbuf;
127
128                 if (lgetfilecon(fc[i], &con) < 0)
129                         continue;
130                 if (lstat(fc[i], &stbuf) == 0) {
131                         if (S_ISLNK(stbuf.st_mode)) {
132                                 if (getfilecon(fc[i], &_con) >= 0) {
133                                         printf(COL_FMT "%s -> %s\n", fc[i], _con, con);
134                                         if (ENABLE_FEATURE_CLEAN_UP)
135                                                 freecon(_con);
136                                 }
137                         } else {
138                                 printf(COL_FMT "%s\n", fc[i], con);
139                         }
140                 }
141                 if (ENABLE_FEATURE_CLEAN_UP)
142                         freecon(con);
143         }
144 }
145
146 int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
147 int sestatus_main(int argc UNUSED_PARAM, char **argv)
148 {
149         unsigned opts;
150         const char *pol_path;
151         int rc;
152
153         opt_complementary = "?0";       /* no arguments are required. */
154         opts = getopt32(argv, "vb");
155
156         /* SELinux status: line */
157         rc = is_selinux_enabled();
158         if (rc < 0)
159                 goto error;
160         printf(COL_FMT "%s\n", "SELinux status:",
161                rc == 1 ? "enabled" : "disabled");
162
163         /* SELinuxfs mount: line */
164         if (!selinux_mnt)
165                 goto error;
166         printf(COL_FMT "%s\n", "SELinuxfs mount:",
167                selinux_mnt);
168
169         /* Current mode: line */
170         rc = security_getenforce();
171         if (rc < 0)
172                 goto error;
173         printf(COL_FMT "%s\n", "Current mode:",
174                rc == 0 ? "permissive" : "enforcing");
175
176         /* Mode from config file: line */
177         if (selinux_getenforcemode(&rc) != 0)
178                 goto error;
179         printf(COL_FMT "%s\n", "Mode from config file:",
180                rc < 0 ? "disabled" : (rc == 0 ? "permissive" : "enforcing"));
181
182         /* Policy version: line */
183         rc = security_policyvers();
184         if (rc < 0)
185                 goto error;
186         printf(COL_FMT "%u\n", "Policy version:", rc);
187
188         /* Policy from config file: line */
189         pol_path = selinux_policy_root();
190         if (!pol_path)
191                 goto error;
192         printf(COL_FMT "%s\n", "Policy from config file:",
193                bb_basename(pol_path));
194
195         if (opts & OPT_BOOLEAN)
196                 display_boolean();
197         if (opts & OPT_VERBOSE)
198                 display_verbose();
199
200         return 0;
201
202   error:
203         bb_perror_msg_and_die("libselinux returns unknown state");
204 }