summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2008-12-03 20:16:41 -0500
committerEamon Walsh <ewalsh@tycho.nsa.gov>2008-12-05 19:20:00 -0500
commit5996217061986aca9f9cc72416b47ddcd2c53329 (patch)
treeb810a1bee0efba87f379dec4c4e9952cefe135b7
parentfc51a30bab530f00a1f373b56ef481e11ed5e000 (diff)
Drop the "level" and "category" rules.
The level and category are currently opaque features of the context. Only a range dominance check is currently supported by the SELinux API. Restoring the rules would require exposing the details of the MLS range (level and category bitmaps) as part of the SELinux API.
-rw-r--r--src/mcscolor.c115
1 files changed, 59 insertions, 56 deletions
diff --git a/src/mcscolor.c b/src/mcscolor.c
index 06d6880..677fcaf 100644
--- a/src/mcscolor.c
+++ b/src/mcscolor.c
@@ -9,6 +9,8 @@
#include <alloca.h>
#include <fnmatch.h>
#include <syslog.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include "mcstrans.h"
@@ -28,23 +30,19 @@ typedef struct setab {
#define COLOR_USER 0
#define COLOR_ROLE 1
#define COLOR_TYPE 2
-#define COLOR_LEVEL 3
-#define COLOR_SENS 4
-#define COLOR_RANGE 5
-#define N_RULES 6
-#define N_COLOR 5
+#define COLOR_RANGE 3
+#define N_COLOR 4
-static char *rules[] = { "user", "role", "type",
- "level", "category", "range" };
+static char *rules[] = { "user", "role", "type", "range" };
-static setab_t *clist[N_RULES];
-static setab_t *cend[N_RULES];
+static setab_t *clist[N_COLOR];
+static setab_t *cend[N_COLOR];
void finish_context_colors(void) {
setab_t *cur, *next;
unsigned i;
- for (i = 0; i < N_RULES; i++) {
+ for (i = 0; i < N_COLOR; i++) {
cur = clist[i];
while(cur) {
next = cur->next;
@@ -60,7 +58,7 @@ static void print_colors(void) {
setab_t *ptr;
unsigned i;
- for (i = 0; i < N_RULES; i++) {
+ for (i = 0; i < N_COLOR; i++) {
ptr = clist[i];
while (ptr) {
printf("%s %s->(fg:%x, bg:%x)\n", rules[i],
@@ -70,15 +68,47 @@ static void print_colors(void) {
}
}
-static const secolor_t *find_color(int idx, const char *raw) {
+static int check_dominance(const char *pattern, const char *raw) {
+ security_context_t ctx;
+ context_t con;
+ unsigned int bit = CONTEXT__CONTAINS;
+ struct av_decision avd;
+ int rc = -1;
+
+ con = context_new(raw);
+ if (!con)
+ return -1;
+ if (context_range_set(con, pattern))
+ goto out;
+ ctx = context_str(con);
+ if (!ctx)
+ goto out;
+
+ rc = security_compute_av_raw(ctx, raw, SECCLASS_CONTEXT, bit, &avd);
+ if (rc)
+ goto out;
+
+ rc = (bit & avd.allowed) != bit;
+out:
+ context_free(con);
+ return rc;
+}
+
+static const secolor_t *find_color(int idx, const char *component,
+ const char *raw) {
setab_t *ptr = clist[idx];
if (raw)
- while(ptr) {
- if (fnmatch(ptr->pattern, raw, 0) == 0)
- return &ptr->color;
- ptr = ptr->next;
+ while (ptr) {
+ if (idx == COLOR_RANGE) {
+ if (check_dominance(ptr->pattern, raw) == 0)
+ return &ptr->color;
+ } else {
+ if (fnmatch(ptr->pattern, component, 0) == 0)
+ return &ptr->color;
}
+ ptr = ptr->next;
+ }
return NULL;
}
@@ -121,7 +151,7 @@ static int process_color(char *buffer, int line) {
ret = sscanf(buffer, "%8s %255s = %x %x", rule, pat, &fg, &bg);
if (ret == 4)
- for (i = 0; i < N_RULES; i++)
+ for (i = 0; i < N_COLOR; i++)
if (!strcmp(rule, rules[i]))
return add_secolor(i, pat, fg, bg);
@@ -150,52 +180,25 @@ int init_colors(void) {
return 0;
}
-static const unsigned precedence[N_COLOR][N_COLOR] = {
- { COLOR_ROLE, COLOR_TYPE, COLOR_RANGE, COLOR_LEVEL, COLOR_SENS },
- { COLOR_USER, COLOR_TYPE, COLOR_RANGE, COLOR_LEVEL, COLOR_SENS },
- { COLOR_USER, COLOR_ROLE, COLOR_RANGE, COLOR_LEVEL, COLOR_SENS },
- { COLOR_RANGE, COLOR_SENS, COLOR_USER, COLOR_ROLE, COLOR_TYPE },
- { COLOR_RANGE, COLOR_LEVEL, COLOR_USER, COLOR_ROLE, COLOR_TYPE }
+static const unsigned precedence[N_COLOR][N_COLOR - 1] = {
+ { COLOR_ROLE, COLOR_TYPE, COLOR_RANGE },
+ { COLOR_USER, COLOR_TYPE, COLOR_RANGE },
+ { COLOR_USER, COLOR_ROLE, COLOR_RANGE },
+ { COLOR_USER, COLOR_ROLE, COLOR_TYPE },
};
static const secolor_t default_color = { 0x000000, 0xffffff };
-static int parse_components(context_t con, char **components)
-{
- char *range, *tmp;
-
+static int parse_components(context_t con, char **components) {
components[COLOR_USER] = (char *)context_user_get(con);
components[COLOR_ROLE] = (char *)context_role_get(con);
components[COLOR_TYPE] = (char *)context_type_get(con);
- components[COLOR_LEVEL] = NULL;
- components[COLOR_SENS] = NULL;
- components[COLOR_RANGE] = NULL;
-
- range = (char *)context_range_get(con);
- if (range) {
- components[COLOR_RANGE] = strdup(range);
-
- tmp = strchr(range, '-');
- if (tmp)
- *tmp = '\0';
- tmp = strchr(range, ':');
- if (tmp) {
- *tmp = '\0';
- components[COLOR_SENS] = strdup(tmp + 1);
- } else
- components[COLOR_SENS] = strdup("");
-
- components[COLOR_LEVEL] = strdup(range);
- }
+ components[COLOR_RANGE] = (char *)context_range_get(con);
return 0;
}
-static void free_components(context_t con, char **components)
-{
- free(components[COLOR_RANGE]);
- free(components[COLOR_LEVEL]);
- free(components[COLOR_SENS]);
+static void free_components(context_t con, char **components) {
context_free(con);
}
@@ -204,8 +207,8 @@ static void free_components(context_t con, char **components)
int raw_color(const security_context_t raw, char **color_str) {
context_t con;
uint32_t i, j, mask = 0;
- const secolor_t *items[N_RULES];
- char *result, *components[N_RULES];
+ const secolor_t *items[N_COLOR];
+ char *result, *components[N_COLOR];
char buf[20];
int rc = -1;
@@ -223,7 +226,7 @@ int raw_color(const security_context_t raw, char **color_str) {
/* find colors for which we have a match */
for (i = 0; i < N_COLOR; i++) {
- items[i] = find_color(i, components[i]);
+ items[i] = find_color(i, components[i], raw);
if (items[i])
mask |= (1 << i);
}
@@ -235,7 +238,7 @@ int raw_color(const security_context_t raw, char **color_str) {
/* propagate colors according to the precedence rules */
for (i = 0; i < N_COLOR; i++)
if (!(mask & (1 << i)))
- for (j = 0; j < N_COLOR; j++)
+ for (j = 0; j < N_COLOR - 1; j++)
if (mask & (1 << precedence[i][j])) {
items[i] = items[precedence[i][j]];
break;