212 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * sestatus -- displays the status of SELinux
 | 
						|
 *
 | 
						|
 * Ported to busybox: KaiGai Kohei <kaigai@ak.jp.nec.com>
 | 
						|
 *
 | 
						|
 * Copyright (C) KaiGai Kohei <kaigai@ak.jp.nec.com>
 | 
						|
 *
 | 
						|
 * Licensed under GPLv2, see file LICENSE in this source tree.
 | 
						|
 */
 | 
						|
 | 
						|
//usage:#define sestatus_trivial_usage
 | 
						|
//usage:       "[-vb]"
 | 
						|
//usage:#define sestatus_full_usage "\n\n"
 | 
						|
//usage:       "	-v	Verbose"
 | 
						|
//usage:     "\n	-b	Display current state of booleans"
 | 
						|
 | 
						|
#include "libbb.h"
 | 
						|
 | 
						|
extern char *selinux_mnt;
 | 
						|
 | 
						|
#define OPT_VERBOSE  (1 << 0)
 | 
						|
#define OPT_BOOLEAN  (1 << 1)
 | 
						|
 | 
						|
#define COL_FMT  "%-31s "
 | 
						|
 | 
						|
static void display_boolean(void)
 | 
						|
{
 | 
						|
	char **bools;
 | 
						|
	int i, active, pending, nbool;
 | 
						|
 | 
						|
	if (security_get_boolean_names(&bools, &nbool) < 0)
 | 
						|
		return;
 | 
						|
 | 
						|
	puts("\nPolicy booleans:");
 | 
						|
 | 
						|
	for (i = 0; i < nbool; i++) {
 | 
						|
		active = security_get_boolean_active(bools[i]);
 | 
						|
		if (active < 0)
 | 
						|
			goto skip;
 | 
						|
		pending = security_get_boolean_pending(bools[i]);
 | 
						|
		if (pending < 0)
 | 
						|
			goto skip;
 | 
						|
		printf(COL_FMT "%s",
 | 
						|
				bools[i], active == 0 ? "off" : "on");
 | 
						|
		if (active != pending)
 | 
						|
			printf(" (%sactivate pending)", pending == 0 ? "in" : "");
 | 
						|
		bb_putchar('\n');
 | 
						|
 skip:
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			free(bools[i]);
 | 
						|
	}
 | 
						|
	if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
		free(bools);
 | 
						|
}
 | 
						|
 | 
						|
static void read_config(char **pc, int npc, char **fc, int nfc)
 | 
						|
{
 | 
						|
	char *buf;
 | 
						|
	parser_t *parser;
 | 
						|
	int pc_ofs = 0, fc_ofs = 0, section = -1;
 | 
						|
 | 
						|
	pc[0] = fc[0] = NULL;
 | 
						|
 | 
						|
	parser = config_open("/etc/sestatus.conf");
 | 
						|
	while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) {
 | 
						|
		if (strcmp(buf, "[process]") == 0) {
 | 
						|
			section = 1;
 | 
						|
		} else if (strcmp(buf, "[files]") == 0) {
 | 
						|
			section = 2;
 | 
						|
		} else {
 | 
						|
			if (section == 1 && pc_ofs < npc -1) {
 | 
						|
				pc[pc_ofs++] = xstrdup(buf);
 | 
						|
				pc[pc_ofs] = NULL;
 | 
						|
			} else if (section == 2 && fc_ofs < nfc - 1) {
 | 
						|
				fc[fc_ofs++] = xstrdup(buf);
 | 
						|
				fc[fc_ofs] = NULL;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	config_close(parser);
 | 
						|
}
 | 
						|
 | 
						|
static void display_verbose(void)
 | 
						|
{
 | 
						|
	security_context_t con, _con;
 | 
						|
	char *fc[50], *pc[50], *cterm;
 | 
						|
	pid_t *pidList;
 | 
						|
	int i;
 | 
						|
 | 
						|
	read_config(pc, ARRAY_SIZE(pc), fc, ARRAY_SIZE(fc));
 | 
						|
 | 
						|
	/* process contexts */
 | 
						|
	puts("\nProcess contexts:");
 | 
						|
 | 
						|
	/* current context */
 | 
						|
	if (getcon(&con) == 0) {
 | 
						|
		printf(COL_FMT "%s\n", "Current context:", con);
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			freecon(con);
 | 
						|
	}
 | 
						|
	/* /sbin/init context */
 | 
						|
	if (getpidcon(1, &con) == 0) {
 | 
						|
		printf(COL_FMT "%s\n", "Init context:", con);
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			freecon(con);
 | 
						|
	}
 | 
						|
 | 
						|
	/* [process] context */
 | 
						|
	for (i = 0; pc[i] != NULL; i++) {
 | 
						|
		pidList = find_pid_by_name(bb_basename(pc[i]));
 | 
						|
		if (pidList[0] > 0 && getpidcon(pidList[0], &con) == 0) {
 | 
						|
			printf(COL_FMT "%s\n", pc[i], con);
 | 
						|
			if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
				freecon(con);
 | 
						|
		}
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			free(pidList);
 | 
						|
	}
 | 
						|
 | 
						|
	/* files contexts */
 | 
						|
	puts("\nFile contexts:");
 | 
						|
 | 
						|
	cterm = xmalloc_ttyname(0);
 | 
						|
//FIXME: if cterm == NULL, we segfault!??
 | 
						|
	puts(cterm);
 | 
						|
	if (cterm && lgetfilecon(cterm, &con) >= 0) {
 | 
						|
		printf(COL_FMT "%s\n", "Controlling term:", con);
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			freecon(con);
 | 
						|
	}
 | 
						|
 | 
						|
	for (i = 0; fc[i] != NULL; i++) {
 | 
						|
		struct stat stbuf;
 | 
						|
 | 
						|
		if (lgetfilecon(fc[i], &con) < 0)
 | 
						|
			continue;
 | 
						|
		if (lstat(fc[i], &stbuf) == 0) {
 | 
						|
			if (S_ISLNK(stbuf.st_mode)) {
 | 
						|
				if (getfilecon(fc[i], &_con) >= 0) {
 | 
						|
					printf(COL_FMT "%s -> %s\n", fc[i], _con, con);
 | 
						|
					if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
						freecon(_con);
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				printf(COL_FMT "%s\n", fc[i], con);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if (ENABLE_FEATURE_CLEAN_UP)
 | 
						|
			freecon(con);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int sestatus_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 | 
						|
int sestatus_main(int argc UNUSED_PARAM, char **argv)
 | 
						|
{
 | 
						|
	unsigned opts;
 | 
						|
	const char *pol_path;
 | 
						|
	int rc;
 | 
						|
 | 
						|
	opt_complementary = "?0";  /* no arguments are required. */
 | 
						|
	opts = getopt32(argv, "vb");
 | 
						|
 | 
						|
	/* SELinux status: line */
 | 
						|
	rc = is_selinux_enabled();
 | 
						|
	if (rc < 0)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%s\n", "SELinux status:",
 | 
						|
	       rc == 1 ? "enabled" : "disabled");
 | 
						|
 | 
						|
	/* SELinuxfs mount: line */
 | 
						|
	if (!selinux_mnt)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%s\n", "SELinuxfs mount:",
 | 
						|
	       selinux_mnt);
 | 
						|
 | 
						|
	/* Current mode: line */
 | 
						|
	rc = security_getenforce();
 | 
						|
	if (rc < 0)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%s\n", "Current mode:",
 | 
						|
	       rc == 0 ? "permissive" : "enforcing");
 | 
						|
 | 
						|
	/* Mode from config file: line */
 | 
						|
	if (selinux_getenforcemode(&rc) != 0)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%s\n", "Mode from config file:",
 | 
						|
	       rc < 0 ? "disabled" : (rc == 0 ? "permissive" : "enforcing"));
 | 
						|
 | 
						|
	/* Policy version: line */
 | 
						|
	rc = security_policyvers();
 | 
						|
	if (rc < 0)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%u\n", "Policy version:", rc);
 | 
						|
 | 
						|
	/* Policy from config file: line */
 | 
						|
	pol_path = selinux_policy_root();
 | 
						|
	if (!pol_path)
 | 
						|
		goto error;
 | 
						|
	printf(COL_FMT "%s\n", "Policy from config file:",
 | 
						|
	       bb_basename(pol_path));
 | 
						|
 | 
						|
	if (opts & OPT_BOOLEAN)
 | 
						|
		display_boolean();
 | 
						|
	if (opts & OPT_VERBOSE)
 | 
						|
		display_verbose();
 | 
						|
 | 
						|
	return 0;
 | 
						|
 | 
						|
  error:
 | 
						|
	bb_perror_msg_and_die("libselinux returns unknown state");
 | 
						|
}
 |