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