whitespace cleanup
[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 source tree.
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 = xmalloc_ttyname(0);
118 //FIXME: if cterm == NULL, we segfault!??
119         puts(cterm);
120         if (cterm && lgetfilecon(cterm, &con) >= 0) {
121                 printf(COL_FMT "%s\n", "Controlling term:", con);
122                 if (ENABLE_FEATURE_CLEAN_UP)
123                         freecon(con);
124         }
125
126         for (i = 0; fc[i] != NULL; i++) {
127                 struct stat stbuf;
128
129                 if (lgetfilecon(fc[i], &con) < 0)
130                         continue;
131                 if (lstat(fc[i], &stbuf) == 0) {
132                         if (S_ISLNK(stbuf.st_mode)) {
133                                 if (getfilecon(fc[i], &_con) >= 0) {
134                                         printf(COL_FMT "%s -> %s\n", fc[i], _con, con);
135                                         if (ENABLE_FEATURE_CLEAN_UP)
136                                                 freecon(_con);
137                                 }
138                         } else {
139                                 printf(COL_FMT "%s\n", fc[i], con);
140                         }
141                 }
142                 if (ENABLE_FEATURE_CLEAN_UP)
143                         freecon(con);
144         }
145 }
146
147 int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
148 int sestatus_main(int argc UNUSED_PARAM, char **argv)
149 {
150         unsigned opts;
151         const char *pol_path;
152         int rc;
153
154         opt_complementary = "?0";  /* no arguments are required. */
155         opts = getopt32(argv, "vb");
156
157         /* SELinux status: line */
158         rc = is_selinux_enabled();
159         if (rc < 0)
160                 goto error;
161         printf(COL_FMT "%s\n", "SELinux status:",
162                rc == 1 ? "enabled" : "disabled");
163
164         /* SELinuxfs mount: line */
165         if (!selinux_mnt)
166                 goto error;
167         printf(COL_FMT "%s\n", "SELinuxfs mount:",
168                selinux_mnt);
169
170         /* Current mode: line */
171         rc = security_getenforce();
172         if (rc < 0)
173                 goto error;
174         printf(COL_FMT "%s\n", "Current mode:",
175                rc == 0 ? "permissive" : "enforcing");
176
177         /* Mode from config file: line */
178         if (selinux_getenforcemode(&rc) != 0)
179                 goto error;
180         printf(COL_FMT "%s\n", "Mode from config file:",
181                rc < 0 ? "disabled" : (rc == 0 ? "permissive" : "enforcing"));
182
183         /* Policy version: line */
184         rc = security_policyvers();
185         if (rc < 0)
186                 goto error;
187         printf(COL_FMT "%u\n", "Policy version:", rc);
188
189         /* Policy from config file: line */
190         pol_path = selinux_policy_root();
191         if (!pol_path)
192                 goto error;
193         printf(COL_FMT "%s\n", "Policy from config file:",
194                bb_basename(pol_path));
195
196         if (opts & OPT_BOOLEAN)
197                 display_boolean();
198         if (opts & OPT_VERBOSE)
199                 display_verbose();
200
201         return 0;
202
203   error:
204         bb_perror_msg_and_die("libselinux returns unknown state");
205 }