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 tarball for details. 9 */ 10 11#include "libbb.h" 12 13extern char *selinux_mnt; 14 15#define OPT_VERBOSE (1 << 0) 16#define OPT_BOOLEAN (1 << 1) 17 18#define COL_FMT "%-31s " 19 20static 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 50static 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 77static 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 147int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 148int 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} 206