int sestatus_main(int argc, 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");
}
Example #2
0
int main(int argc, char **argv)
{
	/* these vars are reused several times */
	int rc, opt, i, c;
	char *context, *root_path;

	/* files that need context checks */
	char *fc[MAX_CHECK];
	char *cterm = ttyname(0);
	int nfc = 0;
	struct stat m;

	/* processes that need context checks */
	char *pc[MAX_CHECK];
	int npc = 0;

	/* booleans */
	char **bools;
	int nbool;

	int verbose = 0;
	int show_bools = 0;

	/* policy */
	const char *pol_name, *root_dir;
	char *pol_path;


	while (1) {
		opt = getopt(argc, argv, "vb");
		if (opt == -1)
			break;
		switch (opt) {
		case 'v':
			verbose = 1;
			break;
		case 'b':
			show_bools = 1;
			break;
		default:
			/* invalid option */
			printf("\nUsage: %s [OPTION]\n\n", basename(argv[0]));
			printf("  -v  Verbose check of process and file contexts.\n");
			printf("  -b  Display current state of booleans.\n");
			printf("\nWithout options, show SELinux status.\n");
			return -1;
		}
	}
	printf_tab("SELinux status:");
	rc = is_selinux_enabled();

	switch (rc) {
	case 1:
		printf("enabled\n");
		break;
	case 0:
		printf("disabled\n");
		return 0;
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		return 0;
		break;
	}

	printf_tab("SELinuxfs mount:");
	if (selinux_mnt != NULL) {
		printf("%s\n", selinux_mnt);
	} else {
		printf("not mounted\n\n");
		printf("Please mount selinuxfs for proper results.\n");
		return -1;
	}

	printf_tab("SELinux root directory:");
	root_dir = selinux_path();
	if (root_dir == NULL) {
		printf("error (%s)\n", strerror(errno));
		return -1;
	}
	/* The path has a trailing '/' so duplicate to edit */
	root_path = strdup(root_dir);
	if (!root_path) {
		printf("malloc error (%s)\n", strerror(errno));
		return -1;
	}
	/* actually blank the '/' */
	root_path[strlen(root_path) - 1] = '\0';
	printf("%s\n", root_path);
	free(root_path);

	/* Dump all the path information */
	printf_tab("Loaded policy name:");
	pol_path = strdup(selinux_policy_root());
	if (pol_path) {
		pol_name = basename(pol_path);
		puts(pol_name);
		free(pol_path);
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Current mode:");
	rc = security_getenforce();
	switch (rc) {
	case 1:
		printf("enforcing\n");
		break;
	case 0:
		printf("permissive\n");
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		break;
	}

	printf_tab("Mode from config file:");
	if (selinux_getenforcemode(&rc) == 0) {
		switch (rc) {
		case 1:
			printf("enforcing\n");
			break;
		case 0:
			printf("permissive\n");
			break;
		case -1:
			printf("disabled\n");
			break;
		}
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Policy MLS status:");
	rc = is_selinux_mls_enabled();
	switch (rc) {
		case 0:
			printf("disabled\n");
			break;
		case 1:
			printf("enabled\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	printf_tab("Policy deny_unknown status:");
	rc = security_deny_unknown();
	switch (rc) {
		case 0:
			printf("allowed\n");
			break;
		case 1:
			printf("denied\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	rc = security_policyvers();
	printf_tab("Max kernel policy version:");
	if (rc < 0)
		printf("unknown (%s)\n", strerror(errno));
	else
		printf("%d\n", rc);


	if (show_bools) {
		/* show booleans */
		if (security_get_boolean_names(&bools, &nbool) >= 0) {
			printf("\nPolicy booleans:\n");

			for (i = 0; i < nbool; i++) {
				if (strlen(bools[i]) + 1 > COL)
					COL = strlen(bools[i]) + 1;
			}
			for (i = 0; i < nbool; i++) {
				printf_tab(bools[i]);

				rc = security_get_boolean_active(bools[i]);
				switch (rc) {
				case 1:
					printf("on");
					break;
				case 0:
					printf("off");
					break;
				default:
					printf("unknown (%s)", strerror(errno));
					break;
				}
				c = security_get_boolean_pending(bools[i]);
				if (c != rc)
					switch (c) {
					case 1:
						printf(" (activate pending)");
						break;
					case 0:
						printf(" (inactivate pending)");
						break;
					default:
						printf(" (pending error: %s)",
						       strerror(errno));
						break;
					}
				printf("\n");

				/* free up the booleans */
				free(bools[i]);
			}
			free(bools);
		}
	}
	/* only show contexts if -v is given */
	if (!verbose)
		return 0;

	load_checks(pc, &npc, fc, &nfc);

	printf("\nProcess contexts:\n");

	printf_tab("Current context:");
	if (getcon(&context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	printf_tab("Init context:");
	if (getpidcon(1, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	for (i = 0; i < npc; i++) {
		rc = pidof(pc[i]);
		if (rc > 0) {
			if (getpidcon(rc, &context) < 0)
				continue;

			printf_tab(pc[i]);
			printf("%s\n", context);
			freecon(context);
		}
	}

	printf("\nFile contexts:\n");

	/* controlling term */
	printf_tab("Controlling terminal:");
	if (lgetfilecon(cterm, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else {
		printf("unknown (%s)\n", strerror(errno));
	}

	for (i = 0; i < nfc; i++) {
		if (lgetfilecon(fc[i], &context) >= 0) {
			printf_tab(fc[i]);

			/* check if this is a symlink */
			if (lstat(fc[i], &m)) {
				printf
				    ("%s (could not check link status (%s)!)\n",
				     context, strerror(errno));
				freecon(context);
				continue;
			}
			if (S_ISLNK(m.st_mode)) {
				/* print link target context */
				printf("%s -> ", context);
				freecon(context);

				if (getfilecon(fc[i], &context) >= 0) {
					printf("%s\n", context);
					freecon(context);
				} else {
					printf("unknown (%s)\n",
					       strerror(errno));
				}
			} else {
				printf("%s\n", context);
				freecon(context);
			}
		}
	}

	return 0;
}
Example #3
0
/*
 * Mount point for selinuxfs. 
 * This definition is private to the function below.
 * Everything else uses the location determined during 
 * libselinux startup via /proc/mounts (see init_selinuxmnt).  
 * We only need the hardcoded definition for the initial mount 
 * required for the initial policy load.
 */
int selinux_init_load_policy(int *enforce)
{
	int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1;
	FILE *cfg;
	char *buf;

	/*
	 * Reread the selinux configuration in case it has changed.
	 * Example:  Caller has chroot'd and is now loading policy from
	 * chroot'd environment.
	 */
	selinux_reset_config();

	/*
	 * Get desired mode (disabled, permissive, enforcing) from 
	 * /etc/selinux/config. 
	 */
	selinux_getenforcemode(&seconfig);

	/* Check for an override of the mode via the kernel command line. */
	rc = mount("proc", "/proc", "proc", 0, 0);
	cfg = fopen("/proc/cmdline", "r");
	if (cfg) {
		char *tmp;
		buf = malloc(selinux_page_size);
		if (!buf) {
			fclose(cfg);
			return -1;
		}
		if (fgets(buf, selinux_page_size, cfg) &&
		    (tmp = strstr(buf, "enforcing="))) {
			if (tmp == buf || isspace(*(tmp - 1))) {
				secmdline =
				    atoi(tmp + sizeof("enforcing=") - 1);
			}
		}
		fclose(cfg);
		free(buf);
	}
#ifndef MNT_DETACH
#define MNT_DETACH 2
#endif
	if (rc == 0)
		umount2("/proc", MNT_DETACH);

	/* 
	 * Determine the final desired mode.
	 * Command line argument takes precedence, then config file. 
	 */
	if (secmdline >= 0)
		*enforce = secmdline;
	else if (seconfig >= 0)
		*enforce = seconfig;
	else
		*enforce = 0;	/* unspecified or disabled */

	/*
	 * Check for the existence of SELinux via selinuxfs, and 
	 * mount it if present for use in the calls below.  
	 */
	if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, 0) < 0 && errno != EBUSY) {
		if (errno == ENODEV) {
			/*
			 * SELinux was disabled in the kernel, either
			 * omitted entirely or disabled at boot via selinux=0.
			 * This takes precedence over any config or
			 * commandline enforcing setting.
			 */
			*enforce = 0;
		} else {
			/* Only emit this error if selinux was not disabled */
			fprintf(stderr, "Mount failed for selinuxfs on %s:  %s\n", SELINUXMNT, strerror(errno));
		}
                
		goto noload;
	}
	set_selinuxmnt(SELINUXMNT);

	/*
	 * Note:  The following code depends on having selinuxfs 
	 * already mounted and selinuxmnt set above.
	 */

	if (seconfig == -1) {
		/* Runtime disable of SELinux. */
		rc = security_disable();
		if (rc == 0) {
			/* Successfully disabled, so umount selinuxfs too. */
			umount(SELINUXMNT);
			fini_selinuxmnt();
		}
		/*
		 * If we failed to disable, SELinux will still be 
		 * effectively permissive, because no policy is loaded. 
		 * No need to call security_setenforce(0) here.
		 */
		goto noload;
	}

	/*
	 * If necessary, change the kernel enforcing status to match 
	 * the desired mode. 
	 */
	orig_enforce = rc = security_getenforce();
	if (rc < 0)
		goto noload;
	if (orig_enforce != *enforce) {
		rc = security_setenforce(*enforce);
		if (rc < 0) {
			fprintf(stderr, "SELinux:  Unable to switch to %s mode:  %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno));
			if (*enforce)
				goto noload;
		}
	}

	/* Load the policy. */
	return selinux_mkload_policy(0);

      noload:
	/*
	 * Only return 0 on a successful completion of policy load.
	 * In any other case, we want to return an error so that init
	 * knows not to proceed with the re-exec for the domain transition.
	 * Depending on the *enforce setting, init will halt (> 0) or proceed
	 * normally (otherwise).
	 */
	return -1;
}