blob: 0bd1a0dda38ace26af11124524a14070a6785273 [file] [log] [blame]
Denis Vlasenko705eaf82007-11-22 01:10:41 +00001/*
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>
Denis Vlasenkodb12d1d2008-12-07 00:52:58 +00007 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02008 * Licensed under GPLv2, see file LICENSE in this source tree.
Denis Vlasenko705eaf82007-11-22 01:10:41 +00009 */
10
Pere Orga5bc8c002011-04-11 03:29:49 +020011//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
Denis Vlasenko705eaf82007-11-22 01:10:41 +000017#include "libbb.h"
18
19extern char *selinux_mnt;
20
Denys Vlasenkofb132e42010-10-29 11:46:52 +020021#define OPT_VERBOSE (1 << 0)
22#define OPT_BOOLEAN (1 << 1)
Denis Vlasenko705eaf82007-11-22 01:10:41 +000023
Denys Vlasenkofb132e42010-10-29 11:46:52 +020024#define COL_FMT "%-31s "
Denis Vlasenko705eaf82007-11-22 01:10:41 +000025
26static 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
56static void read_config(char **pc, int npc, char **fc, int nfc)
57{
Denis Vlasenkoa34f1ed2008-07-20 17:48:59 +000058 char *buf;
59 parser_t *parser;
Denis Vlasenko705eaf82007-11-22 01:10:41 +000060 int pc_ofs = 0, fc_ofs = 0, section = -1;
61
62 pc[0] = fc[0] = NULL;
63
Denis Vlasenkoa34f1ed2008-07-20 17:48:59 +000064 parser = config_open("/etc/sestatus.conf");
Denis Vlasenko084266e2008-07-26 23:08:31 +000065 while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) {
Denis Vlasenko705eaf82007-11-22 01:10:41 +000066 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) {
Denis Vlasenkoc4523c22008-03-28 02:24:59 +000072 pc[pc_ofs++] = xstrdup(buf);
Denis Vlasenko705eaf82007-11-22 01:10:41 +000073 pc[pc_ofs] = NULL;
74 } else if (section == 2 && fc_ofs < nfc - 1) {
Denis Vlasenkoc4523c22008-03-28 02:24:59 +000075 fc[fc_ofs++] = xstrdup(buf);
Denis Vlasenko705eaf82007-11-22 01:10:41 +000076 fc[fc_ofs] = NULL;
77 }
78 }
79 }
Denis Vlasenkoa34f1ed2008-07-20 17:48:59 +000080 config_close(parser);
Denis Vlasenko705eaf82007-11-22 01:10:41 +000081}
82
83static 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
Denis Vlasenko4e12b1a2008-12-23 23:36:47 +0000123 cterm = xmalloc_ttyname(0);
124//FIXME: if cterm == NULL, we segfault!??
Denis Vlasenko705eaf82007-11-22 01:10:41 +0000125 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
Denis Vlasenko4e12b1a2008-12-23 23:36:47 +0000132 for (i = 0; fc[i] != NULL; i++) {
Denis Vlasenko705eaf82007-11-22 01:10:41 +0000133 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
153int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +0000154int sestatus_main(int argc UNUSED_PARAM, char **argv)
Denis Vlasenko705eaf82007-11-22 01:10:41 +0000155{
156 unsigned opts;
157 const char *pol_path;
158 int rc;
159
Denys Vlasenkofb132e42010-10-29 11:46:52 +0200160 opt_complementary = "?0"; /* no arguments are required. */
Denis Vlasenko705eaf82007-11-22 01:10:41 +0000161 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}