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_RANGE] = (char *)context_range_get(con); return 0; }
static int check_selinux_access (const char *changed_user, uid_t changed_uid, access_vector_t requested_access) { int status = -1; security_context_t user_context; context_t c; const char *user; /* if in permissive mode then allow the operation */ if (security_getenforce() == 0) { return 0; } /* get the context of the process which executed passwd */ if (getprevcon(&user_context) != 0) { return -1; } /* get the "user" portion of the context (the part before the first colon) */ c = context_new(user_context); user = context_user_get(c); /* if changing a password for an account with UID==0 or for an account where the identity matches then return success */ if (changed_uid != 0 && strcmp(changed_user, user) == 0) { status = 0; } else { struct av_decision avd; int retval; retval = security_compute_av(user_context, user_context, SECCLASS_PASSWD, requested_access, &avd); if ((retval == 0) && ((requested_access & avd.allowed) == requested_access)) { status = 0; } } context_free(c); freecon(user_context); return status; }
static void disp_con(security_context_t scon) { context_t con = NULL; if (!*scon) { /* --self-exec and --self-fs etc. */ if (opts->disp_user) disp__con_val("user", NULL); if (opts->disp_role) disp__con_val("role", NULL); if (opts->disp_type) disp__con_val("type", NULL); if (opts->disp_sen) disp__con_val("sensitivity", NULL); if (opts->disp_clr) disp__con_val("clearance", NULL); if (opts->disp_mlsr) disp__con_val("mls-range", NULL); return; } if (!(con = context_new(scon))) errx(EXIT_FAILURE, "Couldn't create context from: %s", scon); if (opts->disp_user) disp__con_val("user", context_user_get(con)); if (opts->disp_role) disp__con_val("role", context_role_get(con)); if (opts->disp_type) disp__con_val("type", context_type_get(con)); if (opts->disp_sen) { const char *val = NULL; char *tmp = NULL; val = context_range_get(con); if (!val) val = ""; /* targeted has no "level" etc., any errors should happen at context_new() time */ tmp = strdup(val); if (!tmp) errx(EXIT_FAILURE, "Couldn't create context from: %s", scon); if (strchr(tmp, '-')) *strchr(tmp, '-') = 0; disp__con_val("sensitivity", tmp); free(tmp); } if (opts->disp_clr) { const char *val = NULL; char *tmp = NULL; val = context_range_get(con); if (!val) val = ""; /* targeted has no "level" etc., any errors should happen at context_new() time */ tmp = strdup(val); if (!tmp) errx(EXIT_FAILURE, "Couldn't create context from: %s", scon); if (strchr(tmp, '-')) disp__con_val("clearance", strchr(tmp, '-') + 1); else disp__con_val("clearance", tmp); free(tmp); } if (opts->disp_mlsr) disp__con_val("mls-range", context_range_get(con)); context_free(con); }
/* * do_set_domain * It tries to replace the domain/range of the current context. */ static int do_set_domain(security_context_t old_context, char *domain, server_rec *s) { security_context_t new_context; security_context_t raw_context; context_t context; char *range; /* * Compute the new security context */ context = context_new(old_context); if (!context) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "SELinux: context_new(\"%s\") failed", old_context); return -1; } range = strchr(domain, ':'); if (range) *range++ = '\0'; if (domain && strcmp(domain, "*") != 0) context_type_set(context, domain); if (range && strcmp(range, "*") != 0) context_range_set(context, range); if (range) *--range = ':'; /* fixup */ new_context = context_str(context); if (!new_context) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "SELinux: context_str(\"%s:%s:%s:%s\") failed", context_user_get(context), context_role_get(context), context_type_get(context), context_range_get(context)); context_free(context); return -1; } /* * If old_context == new_context, we don't need to do anything */ if (selinux_trans_to_raw_context(new_context, &raw_context) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "SELinux: selinux_trans_to_raw_context(\"%s\") failed", new_context); context_free(context); return -1; } context_free(context); if (!strcmp(old_context, raw_context)) { freecon(raw_context); return 1; } if (setcon_raw(raw_context) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "SELinux: setcon_raw(\"%s\") failed", raw_context); freecon(raw_context); return -1; } freecon(raw_context); return 0; }
static bool testSELinuxCheckCon(context_t con, const char *user, const char *role, const char *type, int sensMin, int sensMax ATTRIBUTE_UNUSED, int catMin, int catMax) { const char *range; char *tmp; int gotSens; int gotCatOne; int gotCatTwo; if (STRNEQ(context_user_get(con), user)) { fprintf(stderr, "Expect user %s got %s\n", user, context_user_get(con)); return false; } if (STRNEQ(context_role_get(con), role)) { fprintf(stderr, "Expect role %s got %s\n", role, context_role_get(con)); return false; } if (STRNEQ(context_type_get(con), type)) { fprintf(stderr, "Expect type %s got %s\n", type, context_type_get(con)); return false; } range = context_range_get(con); if (range[0] != 's') { fprintf(stderr, "Malformed range %s, cannot find sensitivity\n", range); return false; } if (virStrToLong_i(range + 1, &tmp, 10, &gotSens) < 0 || !tmp) { fprintf(stderr, "Malformed range %s, cannot parse sensitivity\n", range + 1); return false; } if (*tmp != ':') { fprintf(stderr, "Malformed range %s, too many sensitivity values\n", tmp); return false; } tmp++; if (*tmp != 'c') { fprintf(stderr, "Malformed range %s, cannot find first category\n", tmp); return false; } tmp++; if (virStrToLong_i(tmp, &tmp, 10, &gotCatOne) < 0) { fprintf(stderr, "Malformed range %s, cannot parse category one\n", tmp); return false; } if (tmp && *tmp == ',') tmp++; if (tmp && *tmp == 'c') { tmp++; if (virStrToLong_i(tmp, &tmp, 10, &gotCatTwo) < 0) { fprintf(stderr, "Malformed range %s, cannot parse category two\n", tmp); return false; } if (*tmp != '\0') { fprintf(stderr, "Malformed range %s, junk after second category\n", tmp); return false; } if (gotCatOne == gotCatTwo) { fprintf(stderr, "Saw category pair %d,%d where cats were equal\n", gotCatOne, gotCatTwo); return false; } } else { gotCatTwo = gotCatOne; } if (gotSens != sensMin) { fprintf(stderr, "Sensitivity %d is not equal to min %d\n", gotSens, sensMin); return false; } if (gotCatOne < catMin || gotCatOne > catMax) { fprintf(stderr, "Category one %d is out of range %d-%d\n", gotCatTwo, catMin, catMax); return false; } if (gotCatTwo < catMin || gotCatTwo > catMax) { fprintf(stderr, "Category two %d is out of range %d-%d\n", gotCatTwo, catMin, catMax); return false; } if (gotCatOne > gotCatTwo) { fprintf(stderr, "Category one %d is greater than category two %d\n", gotCatOne, gotCatTwo); return false; } return true; }