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