Added CONFIG_CLEAR and CONFIG_RESET to config.maemo
[busybox4maemo] / 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[256];
51         FILE *fp;
52         int pc_ofs = 0, fc_ofs = 0, section = -1;
53
54         pc[0] = fc[0] = NULL;
55
56         fp = fopen("/etc/sestatus.conf", "rb");
57         if (fp == NULL)
58                 return;
59
60         while (fgets(buf, sizeof(buf), fp) != NULL) {
61                 int i, c;
62
63                 /* kills comments */
64                 for (i = 0; (c = buf[i]) != '\0'; i++) {
65                         if (c == '#') {
66                                 buf[i] = '\0';
67                                 break;
68                         }
69                 }
70                 trim(buf);
71
72                 if (buf[0] == '\0')
73                         continue;
74
75                 if (strcmp(buf, "[process]") == 0) {
76                         section = 1;
77                 } else if (strcmp(buf, "[files]") == 0) {
78                         section = 2;
79                 } else {
80                         if (section == 1 && pc_ofs < npc -1) {
81                                 pc[pc_ofs++] = strdup(buf);
82                                 pc[pc_ofs] = NULL;
83                         } else if (section == 2 && fc_ofs < nfc - 1) {
84                                 fc[fc_ofs++] = strdup(buf);
85                                 fc[fc_ofs] = NULL;
86                         }
87                 }
88         }
89         fclose(fp);
90 }
91
92 static void display_verbose(void)
93 {
94         security_context_t con, _con;
95         char *fc[50], *pc[50], *cterm;
96         pid_t *pidList;
97         int i;
98
99         read_config(pc, ARRAY_SIZE(pc), fc, ARRAY_SIZE(fc));
100
101         /* process contexts */
102         puts("\nProcess contexts:");
103
104         /* current context */
105         if (getcon(&con) == 0) {
106                 printf(COL_FMT "%s\n", "Current context:", con);
107                 if (ENABLE_FEATURE_CLEAN_UP)
108                         freecon(con);
109         }
110         /* /sbin/init context */
111         if (getpidcon(1, &con) == 0) {
112                 printf(COL_FMT "%s\n", "Init context:", con);
113                 if (ENABLE_FEATURE_CLEAN_UP)
114                         freecon(con);
115         }
116
117         /* [process] context */
118         for (i = 0; pc[i] != NULL; i++) {
119                 pidList = find_pid_by_name(bb_basename(pc[i]));
120                 if (pidList[0] > 0 && getpidcon(pidList[0], &con) == 0) {
121                         printf(COL_FMT "%s\n", pc[i], con);
122                         if (ENABLE_FEATURE_CLEAN_UP)
123                                 freecon(con);
124                 }
125                 if (ENABLE_FEATURE_CLEAN_UP)
126                         free(pidList);
127         }
128
129         /* files contexts */
130         puts("\nFile contexts:");
131
132         cterm = ttyname(0);
133         puts(cterm);
134         if (cterm && lgetfilecon(cterm, &con) >= 0) {
135                 printf(COL_FMT "%s\n", "Controlling term:", con);
136                 if (ENABLE_FEATURE_CLEAN_UP)
137                         freecon(con);
138         }
139
140         for (i=0; fc[i] != NULL; i++) {
141                 struct stat stbuf;
142
143                 if (lgetfilecon(fc[i], &con) < 0)
144                         continue;
145                 if (lstat(fc[i], &stbuf) == 0) {
146                         if (S_ISLNK(stbuf.st_mode)) {
147                                 if (getfilecon(fc[i], &_con) >= 0) {
148                                         printf(COL_FMT "%s -> %s\n", fc[i], _con, con);
149                                         if (ENABLE_FEATURE_CLEAN_UP)
150                                                 freecon(_con);
151                                 }
152                         } else {
153                                 printf(COL_FMT "%s\n", fc[i], con);
154                         }
155                 }
156                 if (ENABLE_FEATURE_CLEAN_UP)
157                         freecon(con);
158         }
159 }
160
161 int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
162 int sestatus_main(int argc ATTRIBUTE_UNUSED, char **argv)
163 {
164         unsigned opts;
165         const char *pol_path;
166         int rc;
167
168         opt_complementary = "?0";       /* no arguments are required. */
169         opts = getopt32(argv, "vb");
170
171         /* SELinux status: line */
172         rc = is_selinux_enabled();
173         if (rc < 0)
174                 goto error;
175         printf(COL_FMT "%s\n", "SELinux status:",
176                rc == 1 ? "enabled" : "disabled");
177
178         /* SELinuxfs mount: line */
179         if (!selinux_mnt)
180                 goto error;
181         printf(COL_FMT "%s\n", "SELinuxfs mount:",
182                selinux_mnt);
183
184         /* Current mode: line */
185         rc = security_getenforce();
186         if (rc < 0)
187                 goto error;
188         printf(COL_FMT "%s\n", "Current mode:",
189                rc == 0 ? "permissive" : "enforcing");
190
191         /* Mode from config file: line */
192         if (selinux_getenforcemode(&rc) != 0)
193                 goto error;
194         printf(COL_FMT "%s\n", "Mode from config file:",
195                rc < 0 ? "disabled" : (rc == 0 ? "permissive" : "enforcing"));
196
197         /* Policy version: line */
198         rc = security_policyvers();
199         if (rc < 0)
200                 goto error;
201         printf(COL_FMT "%u\n", "Policy version:", rc);
202
203         /* Policy from config file: line */
204         pol_path = selinux_policy_root();
205         if (!pol_path)
206                 goto error;
207         printf(COL_FMT "%s\n", "Policy from config file:",
208                bb_basename(pol_path));
209
210         if (opts & OPT_BOOLEAN)
211                 display_boolean();
212         if (opts & OPT_VERBOSE)
213                 display_verbose();
214
215         return 0;
216
217   error:
218         bb_perror_msg_and_die("libselinux returns unknown state");
219 }