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