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
  11//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
  17#include "libbb.h"
  18
  19extern char *selinux_mnt;
  20
  21#define OPT_VERBOSE  (1 << 0)
  22#define OPT_BOOLEAN  (1 << 1)
  23
  24#define COL_FMT  "%-31s "
  25
  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{
  58        char *buf;
  59        parser_t *parser;
  60        int pc_ofs = 0, fc_ofs = 0, section = -1;
  61
  62        pc[0] = fc[0] = NULL;
  63
  64        parser = config_open("/etc/sestatus.conf");
  65        while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) {
  66                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) {
  72                                pc[pc_ofs++] = xstrdup(buf);
  73                                pc[pc_ofs] = NULL;
  74                        } else if (section == 2 && fc_ofs < nfc - 1) {
  75                                fc[fc_ofs++] = xstrdup(buf);
  76                                fc[fc_ofs] = NULL;
  77                        }
  78                }
  79        }
  80        config_close(parser);
  81}
  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
 123        cterm = xmalloc_ttyname(0);
 124//FIXME: if cterm == NULL, we segfault!??
 125        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
 132        for (i = 0; fc[i] != NULL; i++) {
 133                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;
 154int sestatus_main(int argc UNUSED_PARAM, char **argv)
 155{
 156        unsigned opts;
 157        const char *pol_path;
 158        int rc;
 159
 160        opt_complementary = "?0";  /* no arguments are required. */
 161        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}
 212