Hello,
On Thu, 17 Jul 2008, Joshua Brindle wrote:
> split the layout changes from the functional changes and
> submit 2 patches please.
All right, here they come, I hope they are okay now.
Please apply the patches in this order:
1) sestatus-layout.patch
2) sestatus-functionality.patch
Best regards,
vmk
--
************************************************************************
Tietotekniikkaosasto / Helsingin yliopisto
IT Department / University of Helsinki
************************************************************************
--- policycoreutils-2.0.46/sestatus/sestatus.c 2008-03-18 22:57:01.000000000 +0200
+++ policycoreutils-2.0.46-vmk/sestatus/sestatus.c 2008-07-17 18:46:39.000000000 +0300
@@ -3,20 +3,22 @@
* Distributed under the terms of the GNU General Public License v2
* $Header: /home/cvsroot/gentoo-projects/hardened/policycoreutils-extra/src/sestatus.c,v 1.10 2004/03/26 19:25:52 pebenito Exp $
* Patch provided by Steve Grubb
+ * Refactored by Vesa-Matti Kari
*/
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-#include <selinux/get_default_type.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
#include <unistd.h>
-#include <libgen.h>
-#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <selinux/get_default_type.h>
+#include <selinux/selinux.h>
#define PROC_BASE "/proc"
#define MAX_CHECK 50
@@ -60,7 +62,6 @@
int pidof(const char *command)
{
-/* inspired by killall5.c from psmisc */
DIR *dir;
struct dirent *de;
int pid, ret = -1, self = getpid();
@@ -169,82 +170,44 @@
}
-int main(int argc, char **argv)
+static int status_show(void)
{
- /* these vars are reused several times */
- int rc, opt, i, c;
- char *context;
-
- /* 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;
- 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("\nWithout options, show SELinux status.\n");
- return -1;
- }
- }
printf_tab("SELinux status:");
- rc = is_selinux_enabled();
- switch (rc) {
+ switch (is_selinux_enabled()) {
case 1:
printf("enabled\n");
+ return 1;
break;
case 0:
printf("disabled\n");
return 0;
break;
default:
- printf("unknown (%s)\n", strerror(errno));
+ printf("unknown (%s)\n", strerror(errno));
return 0;
break;
}
+}
+static int mount_show(const char *mnt)
+{
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;
- }
+ if (mnt) {
+ printf("%s\n", mnt);
+ return 0;
+ }
+
+ fprintf(stderr, "not mounted\n\nPlease mount selinuxfs for proper results.\n");
+ return -1;
+}
+
+static void mode_show(void)
+{
printf_tab("Current mode:");
- rc = security_getenforce();
- switch (rc) {
+
+ switch (security_getenforce()) {
case 1:
printf("enforcing\n");
break;
@@ -255,8 +218,14 @@
printf("unknown (%s)\n", strerror(errno));
break;
}
+}
+
+static void confmode_show(void)
+{
+ int rc;
printf_tab("Mode from config file:");
+
if (selinux_getenforcemode(&rc) == 0) {
switch (rc) {
case 1:
@@ -269,81 +238,98 @@
printf("disabled\n");
break;
}
- } else {
+ } else
printf("error (%s)\n", strerror(errno));
- }
+}
+
+static void policyvers_show(void)
+{
+ int rc;
- rc = security_policyvers();
printf_tab("Policy version:");
+
+ rc = security_policyvers();
if (rc < 0)
printf("unknown (%s)\n", strerror(errno));
else
printf("%d\n", rc);
+}
+
+static void confpolicyvers_show(void)
+{
+ const char *pol_name;
+ char *pol_path;
- /* Dump all the path information */
printf_tab("Policy from config file:");
+
pol_path = strdup(selinux_policy_root());
- if (pol_path) {
- pol_name = basename(pol_path);
- puts(pol_name);
- free(pol_path);
- } else {
+ if (!pol_path) {
printf("error (%s)\n", strerror(errno));
+ return;
}
- 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]);
+ pol_name = basename(pol_path);
+ puts(pol_name);
+ free(pol_path);
+}
- rc = security_get_boolean_active(bools[i]);
- switch (rc) {
+static void bools_show(unsigned int *column)
+{
+ char **bools;
+ int nbool;
+ int c, i, rc;
+
+ rc = security_get_boolean_names(&bools, &nbool);
+ if (rc < 0)
+ return;
+
+ printf("Policy booleans:\n");
+
+ for (i = 0; i < nbool; i++)
+ if (strlen(bools[i]) + 1 > *column)
+ *column = 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("on");
+ printf(" (activate pending)");
break;
case 0:
- printf("off");
+ printf(" (inactivate pending)");
break;
default:
- printf("unknown (%s)", strerror(errno));
+ printf(" (pending error: %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");
+ printf("\n");
- /* free up the booleans */
- free(bools[i]);
- }
- free(bools);
+ free(bools[i]);
}
- }
- /* only show contexts if -v is given */
- if (!verbose)
- return 0;
+ free(bools);
+}
- load_checks(pc, &npc, fc, &nfc);
+static void proccon_show(char *pc[], int npc)
+{
+ char *context;
+ int i, rc;
- printf("\nProcess contexts:\n");
+ printf("Process contexts:\n");
printf_tab("Current context:");
if (getcon(&context) >= 0) {
@@ -371,10 +357,22 @@
}
}
- printf("\nFile contexts:\n");
+ for (i = 0; i < npc; i++)
+ free(pc[i]);
+}
+
+static void filecon_show(char *fc[], int nfc)
+{
+ struct stat st;
+ char *context;
+ char *cterm;
+ int i;
+
+ printf("File contexts:\n");
- /* controlling term */
printf_tab("Controlling term:");
+
+ cterm = ttyname(0);
if (lgetfilecon(cterm, &context) >= 0) {
printf("%s\n", context);
freecon(context);
@@ -387,14 +385,13 @@
printf_tab(fc[i]);
/* check if this is a symlink */
- if (lstat(fc[i], &m)) {
- printf
- ("%s (could not check link status (%s)!)\n",
+ if (lstat(fc[i], &st)) {
+ printf ("%s (could not check link status (%s)!)\n",
context, strerror(errno));
freecon(context);
continue;
}
- if (S_ISLNK(m.st_mode)) {
+ if (S_ISLNK(st.st_mode)) {
/* print link target context */
printf("%s -> ", context);
freecon(context);
@@ -402,16 +399,79 @@
if (getfilecon(fc[i], &context) >= 0) {
printf("%s\n", context);
freecon(context);
- } else {
- printf("unknown (%s)\n",
- strerror(errno));
- }
+ } else
+ printf("unknown (%s)\n", strerror(errno));
} else {
printf("%s\n", context);
freecon(context);
}
+ }
+ }
+
+ for (i = 0; i < nfc; i++)
+ free(fc[i]);
+}
+
+int main(int argc, char *argv[])
+{
+ char *pc[MAX_CHECK]; /* processes that need context checks */
+ char *fc[MAX_CHECK]; /* files that need context checks */
+ int npc, nfc;
+ int verbose, bools;
+ int rc, opt;
+
+ npc = nfc = 0;
+ verbose = bools = 0;
+
+ while (1) {
+ opt = getopt(argc, argv, "vb");
+ if (opt == -1)
+ break;
+ switch (opt) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'b':
+ bools = 1;
+ break;
+ default:
+ fprintf(stderr, "\nUsage: %s [OPTION]\n\n", basename(argv[0]));
+ fprintf(stderr, " -v Verbose check of process and file contexts.\n");
+ fprintf(stderr, "\nWithout options, show SELinux status.\n");
+ return -1;
}
}
+ rc = status_show();
+ if (rc < 1) {
+ return rc;
+ }
+
+ rc = mount_show(selinux_mnt);
+ if (rc < 0) {
+ return rc;
+ }
+
+ mode_show();
+ confmode_show();
+ policyvers_show();
+ confpolicyvers_show();
+
+ if (bools) {
+ putchar('\n');
+ bools_show(&COL);
+ }
+
+ if (!verbose)
+ return 0;
+
+ load_checks(pc, &npc, fc, &nfc);
+
+ putchar('\n');
+ proccon_show(pc, npc);
+
+ putchar('\n');
+ filecon_show(fc, nfc);
+
return 0;
}
--- policycoreutils-2.0.46/sestatus/sestatus.c 2008-07-17 18:51:41.000000000 +0300
+++ policycoreutils-2.0.46-vmk/sestatus/sestatus.c 2008-07-17 18:45:11.000000000 +0300
@@ -20,152 +20,156 @@
#include <selinux/get_default_type.h>
#include <selinux/selinux.h>
+
#define PROC_BASE "/proc"
#define MAX_CHECK 50
#define CONF "/etc/sestatus.conf"
+#define INIT_PROC_PID (pid_t)1
/* conf file sections */
#define PROCS "[process]"
#define FILES "[files]"
-/* buffer size for cmp_cmdline */
+/* buffer size for cmp_cmdline() and load_checks() */
#define BUFSIZE 255
+
/* column to put the output (must be a multiple of 8) */
static unsigned int COL = 32;
extern char *selinux_mnt;
-int cmp_cmdline(const char *command, int pid)
-{
+static int cmp_cmdline(const char *command, pid_t pid)
+{
char buf[BUFSIZE];
char filename[BUFSIZE];
- memset(buf, '\0', BUFSIZE);
+ memset(buf, '\0', sizeof buf);
- /* first read the proc entry */
- sprintf(filename, "%s/%d/exe", PROC_BASE, pid);
+ snprintf(filename, sizeof filename, "%s/%d/exe", PROC_BASE, pid);
- if (readlink(filename, buf, BUFSIZE) < 0)
+ if (readlink(filename, buf, sizeof buf) < 0)
return 0;
- if (buf[BUFSIZE - 1] != '\0')
- buf[BUFSIZE - 1] = '\0';
+ if (buf[sizeof buf - 1] != '\0')
+ buf[sizeof buf - 1] = '\0';
- /* check if this is the command we're looking for. */
- if (strcmp(command, buf) == 0)
- return 1;
- else
- return 0;
+ return !strcmp(command, buf);
}
-int pidof(const char *command)
+static int pidof(const char *command, pid_t *pid)
{
DIR *dir;
struct dirent *de;
- int pid, ret = -1, self = getpid();
+ pid_t self;
+ int rc;
+
+ rc = -1;
- if (!(dir = opendir(PROC_BASE))) {
- perror(PROC_BASE);
- return -1;
+ dir = opendir(PROC_BASE);
+ if (!dir) {
+ fprintf(stderr, "Unable to open %s: %s", PROC_BASE, strerror(errno));
+ return rc;
}
- while ((de = readdir(dir)) != NULL) {
+ self = getpid();
+ while ((de = readdir(dir))) {
errno = 0;
- pid = (int)strtol(de->d_name, (char **)NULL, 10);
- if (errno || pid == 0 || pid == self)
+ *pid = (pid_t)strtol(de->d_name, NULL, 10);
+ if (errno || *pid == 0 || *pid == self)
continue;
- if (cmp_cmdline(command, pid)) {
- ret = pid;
+ if (cmp_cmdline(command, *pid)) {
+ rc = 0;
break;
}
}
closedir(dir);
- return ret;
+ return rc;
}
-void load_checks(char *pc[], int *npc, char *fc[], int *nfc)
+static void load_checks(char *pc[], int *npc, char *fc[], int *nfc)
{
+ FILE *fp;
+ char buf[BUFSIZE];
+ char *bufp;
+ int buflen, section;
+ int i;
- FILE *fp = fopen(CONF, "r");
- char buf[255], *bufp;
- int buf_len, section = -1;
- int proclen = strlen(PROCS);
- int filelen = strlen(FILES);
-
- if (fp == NULL) {
- printf("\nUnable to open %s.\n", CONF);
+ fp = fopen(CONF, "r");
+ if (!fp) {
+ fprintf(stderr, "\nUnable to open %s: %s\n", CONF, strerror(errno));
return;
}
- while (!feof(fp)) {
- if (!fgets(buf, sizeof buf, fp))
- break;
+ section = -1;
+
+ while (fgets(buf, sizeof buf, fp)) {
- buf_len = strlen(buf);
- if (buf[buf_len - 1] == '\n')
- buf[buf_len - 1] = 0;
+ buflen = strlen(buf);
+ if (buf[buflen - 1] == '\n')
+ buf[buflen - 1] = '\0';
bufp = buf;
- while (*bufp && isspace(*bufp)) {
+ while (*bufp && isspace(*bufp))
bufp++;
- buf_len--;
- }
- if (*bufp == '#')
- /* skip comments */
+ if (*bufp == '#' || *bufp == '\0')
continue;
- if (*bufp) {
- if (!(*bufp))
- goto out;
-
- if (strncmp(bufp, PROCS, proclen) == 0)
- section = 0;
- else if (strncmp(bufp, FILES, filelen) == 0)
- section = 1;
- else {
- switch (section) {
- case 0:
- if (*npc >= MAX_CHECK)
- break;
- pc[*npc] =
- (char *)malloc((buf_len) *
- sizeof(char));
- memcpy(pc[*npc], bufp, buf_len);
- (*npc)++;
- bufp = NULL;
- break;
- case 1:
- if (*nfc >= MAX_CHECK)
- break;
- fc[*nfc] =
- (char *)malloc((buf_len) *
- sizeof(char));
- memcpy(fc[*nfc], bufp, buf_len);
- (*nfc)++;
- bufp = NULL;
+ if (!strncmp(bufp, PROCS, sizeof PROCS))
+ section = 0;
+ else if (!strncmp(bufp, FILES, sizeof FILES))
+ section = 1;
+ else {
+ switch (section) {
+ case 0:
+ if (*npc >= MAX_CHECK)
break;
- default:
- /* ignore lines before a section */
- printf("Line not in a section: %s.\n",
- buf);
+ pc[*npc] = strdup(bufp);
+ if (!pc[*npc])
+ goto outfree;
+ (*npc)++;
+ break;
+ case 1:
+ if (*nfc >= MAX_CHECK)
break;
- }
+ fc[*nfc] = strdup(bufp);
+ if (!fc[*nfc])
+ goto outfree;
+ (*nfc)++;
+ break;
+ default:
+ /* ignore lines before a section */
+ printf("Line not in a section: %s.\n", buf);
+ break;
}
}
}
- out:
+
+ if (ferror(fp)) {
+ fprintf(stderr, "\nError while reading %s: %s\n", CONF, strerror(errno));
+ goto outfree;
+ }
+
+out:
fclose(fp);
return;
+
+outfree:
+ for (i = 0; i < *npc && i < MAX_CHECK; i++)
+ free(pc[i]);
+ for (i = 0; i < *nfc && i < MAX_CHECK; i++)
+ free(fc[i]);
+ *npc = *nfc = 0;
+ goto out;
}
-void printf_tab(const char *outp)
+static void printf_tab(const char *outp)
{
char buf[20];
- snprintf(buf, sizeof(buf), "%%-%us", COL);
+ snprintf(buf, sizeof buf, "%%-%us", COL);
printf(buf, outp);
}
@@ -327,6 +331,7 @@
static void proccon_show(char *pc[], int npc)
{
char *context;
+ pid_t pid;
int i, rc;
printf("Process contexts:\n");
@@ -339,22 +344,24 @@
printf("unknown (%s)\n", strerror(errno));
printf_tab("Init context:");
- if (getpidcon(1, &context) >= 0) {
+ if (getpidcon(INIT_PROC_PID, &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;
+ rc = pidof(pc[i], &pid);
- printf_tab(pc[i]);
- printf("%s\n", context);
- freecon(context);
- }
+ if (rc < 0)
+ continue;
+
+ if (getpidcon(pid, &context) < 0)
+ continue;
+
+ printf_tab(pc[i]);
+ printf("%s\n", context);
+ freecon(context);
}
for (i = 0; i < npc; i++)
@@ -365,20 +372,23 @@
{
struct stat st;
char *context;
- char *cterm;
+ char *ctrlterm;
int i;
printf("File contexts:\n");
printf_tab("Controlling term:");
- cterm = ttyname(0);
- if (lgetfilecon(cterm, &context) >= 0) {
- printf("%s\n", context);
- freecon(context);
- } else {
- printf("unknown (%s)\n", strerror(errno));
- }
+ ctrlterm = ttyname(STDIN_FILENO);
+ if (ctrlterm) {
+ if (lgetfilecon(ctrlterm, &context) >= 0) {
+ printf("%s\n", context);
+ freecon(context);
+ } else {
+ printf("unknown (%s)\n", strerror(errno));
+ }
+ } else
+ printf("error: %s\n", strerror(errno));
for (i = 0; i < nfc; i++) {
if (lgetfilecon(fc[i], &context) >= 0) {
@@ -436,6 +446,7 @@
break;
default:
fprintf(stderr, "\nUsage: %s [OPTION]\n\n", basename(argv[0]));
+ fprintf(stderr, " -b Display the current state of booleans.\n");
fprintf(stderr, " -v Verbose check of process and file contexts.\n");
fprintf(stderr, "\nWithout options, show SELinux status.\n");
return -1;
#!/bin/bash
#
# PURPOSE: compare old and new sestatus output
# NOTE: run this in policycoreutils-X-Y-ZZ/sestatus
OLD=/usr/sbin/sestatus
NEW=$PWD/sestatus
OOUT=/tmp/old
NOUT=/tmp/new
i=0
for arg in '' '-b' '-v' '-vb'; do
((i++))
echo -n "$OLD $arg => "
$OLD $arg > $OOUT &&
$NEW $arg > $NOUT &&
diff $OOUT $NOUT &&
echo test $i okay ||
echo test $i failed
done
rm -f $OOUT $NOUT