apol_mls_range_t *apol_mls_range_create_from_literal(const char *mls_range_string) { if (mls_range_string == NULL) { errno = EINVAL; return NULL; } apol_mls_range_t *r = apol_mls_range_create(); if (r == NULL) { return NULL; } char *dash; if ((dash = strchr(mls_range_string, '-')) == NULL) { // just a low level apol_mls_level_t *l = apol_mls_level_create_from_literal(mls_range_string); if (l == NULL) { apol_mls_range_destroy(&r); return NULL; } r->low = l; } else { // both a low and a high level if (dash == mls_range_string) { apol_mls_range_destroy(&r); errno = EINVAL; return NULL; } char *s = strndup(mls_range_string, dash - mls_range_string); if (s == NULL) { apol_mls_range_destroy(&r); return NULL; } apol_mls_level_t *l = apol_mls_level_create_from_literal(s); if (l == NULL) { apol_mls_range_destroy(&r); free(s); return NULL; } r->low = l; free(s); l = NULL; if ((l = apol_mls_level_create_from_literal(dash + 1)) == NULL) { apol_mls_range_destroy(&r); return NULL; } r->high = l; } return r; }
void apol_context_destroy(apol_context_t ** context) { if (*context != NULL) { free((*context)->user); free((*context)->role); free((*context)->type); apol_mls_range_destroy(&((*context)->range)); free(*context); *context = NULL; } }
int apol_context_set_range(const apol_policy_t * p, apol_context_t * context, apol_mls_range_t * range) { if (context == NULL) { ERR(p, "%s", strerror(EINVAL)); errno = EINVAL; return -1; } if (range != context->range) { apol_mls_range_destroy(&(context->range)); context->range = range; } return 0; }
apol_mls_range_t *apol_mls_range_create_from_mls_range(const apol_mls_range_t * range) { apol_mls_range_t *r; if ((r = apol_mls_range_create()) == NULL) { return NULL; } if (range != NULL && ((r->low = apol_mls_level_create_from_mls_level(range->low)) == NULL || (r->high = apol_mls_level_create_from_mls_level(range->high)) == NULL)) { apol_mls_range_destroy(&r); return NULL; } return r; }
apol_mls_range_t *apol_mls_range_create_from_qpol_mls_range(const apol_policy_t * p, const qpol_mls_range_t * qpol_range) { apol_mls_range_t *apol_range = NULL; const qpol_mls_level_t *tmp = NULL; apol_mls_level_t *tmp_lvl = NULL; int error = 0; if (!p || !qpol_range) { ERR(p, "%s", strerror(EINVAL)); errno = EINVAL; return NULL; } apol_range = calloc(1, sizeof(apol_mls_range_t)); if (!apol_range) { ERR(p, "%s", strerror(ENOMEM)); return NULL; } /* low */ if (qpol_mls_range_get_low_level(p->p, qpol_range, &tmp) || !(tmp_lvl = apol_mls_level_create_from_qpol_mls_level(p, tmp)) || apol_mls_range_set_low(p, apol_range, tmp_lvl)) { error = errno; apol_mls_level_destroy(&tmp_lvl); goto err; } tmp_lvl = NULL; /* high */ if (qpol_mls_range_get_high_level(p->p, qpol_range, &tmp) || !(tmp_lvl = apol_mls_level_create_from_qpol_mls_level(p, tmp)) || apol_mls_range_set_high(p, apol_range, tmp_lvl)) { error = errno; apol_mls_level_destroy(&tmp_lvl); goto err; } return apol_range; err: apol_mls_range_destroy(&apol_range); errno = error; return NULL; }
apol_context_t *apol_context_create_from_qpol_context(const apol_policy_t * p, const qpol_context_t * context) { apol_context_t *c = NULL; const qpol_user_t *user; const qpol_role_t *role; const qpol_type_t *type; const qpol_mls_range_t *range; const char *user_name, *role_name, *type_name; apol_mls_range_t *apol_range = NULL; if ((c = apol_context_create()) == NULL) { ERR(p, "%s", strerror(ENOMEM)); goto err; } if (qpol_context_get_user(p->p, context, &user) < 0 || qpol_context_get_role(p->p, context, &role) < 0 || qpol_context_get_type(p->p, context, &type) < 0 || qpol_context_get_range(p->p, context, &range) < 0) { goto err; } if (qpol_user_get_name(p->p, user, &user_name) < 0 || qpol_role_get_name(p->p, role, &role_name) < 0 || qpol_type_get_name(p->p, type, &type_name) < 0) { goto err; } if (qpol_policy_has_capability(p->p, QPOL_CAP_MLS)) { /* if the policy is MLS then convert the range, else * rely upon the default value of NULL */ if ((apol_range = apol_mls_range_create_from_qpol_mls_range(p, range)) == NULL) { goto err; } } if (apol_context_set_user(p, c, user_name) < 0 || apol_context_set_role(p, c, role_name) < 0 || apol_context_set_type(p, c, type_name) < 0 || apol_context_set_range(p, c, apol_range) < 0) { goto err; } return c; err: apol_mls_range_destroy(&apol_range); apol_context_destroy(&c); return NULL; }
/** * Gets a textual representation of a user, and * all of that user's roles. * * @param type_datum Reference to sepol type_datum * @param policydb Reference to a policy * roles */ static PyObject* get_user(const qpol_user_t * user_datum, const apol_policy_t * policydb) { int error = 0; int rt; const qpol_role_t *role_datum = NULL; qpol_iterator_t *iter = NULL; const qpol_mls_range_t *range = NULL; const qpol_mls_level_t *dflt_level = NULL; apol_mls_level_t *ap_lvl = NULL; apol_mls_range_t *ap_range = NULL; qpol_policy_t *q = apol_policy_get_qpol(policydb); char *tmp = NULL; const char *user_name, *role_name; PyObject *dict = NULL; PyObject *list = PyList_New(0); if (!list) goto err; if (qpol_user_get_name(q, user_datum, &user_name)) goto err; dict = PyDict_New(); if (!dict) goto err; if (py_insert_string(dict, "name", user_name)) goto err; if (qpol_policy_has_capability(q, QPOL_CAP_MLS)) { if (qpol_user_get_dfltlevel(q, user_datum, &dflt_level)) goto err; ap_lvl = apol_mls_level_create_from_qpol_mls_level(policydb, dflt_level); tmp = apol_mls_level_render(policydb, ap_lvl); if (!tmp) goto err; if (py_insert_string(dict, "level", tmp)) goto err; free(tmp); tmp = NULL; if (qpol_user_get_range(q, user_datum, &range)) goto err; ap_range = apol_mls_range_create_from_qpol_mls_range(policydb, range); tmp = apol_mls_range_render(policydb, ap_range); if (!tmp) goto err; if (py_insert_string(dict, "range", tmp)) goto err; free(tmp); tmp=NULL; } if (qpol_user_get_role_iter(q, user_datum, &iter)) goto err; for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&role_datum)) goto err; if (qpol_role_get_name(q, role_datum, &role_name)) goto err; if (py_append_string(list, role_name)) goto err; } rt = py_insert_obj(dict, "roles", list); Py_DECREF(list); list=NULL; if (rt) goto err; goto cleanup; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(errno)); py_decref(list); list=NULL; py_decref(dict); dict=NULL; cleanup: free(tmp); qpol_iterator_destroy(&iter); apol_mls_level_destroy(&ap_lvl); apol_mls_range_destroy(&ap_range); errno = error; return dict; }
int apol_context_validate_partial(const apol_policy_t * p, const apol_context_t * context) { apol_user_query_t *user_query = NULL; apol_role_query_t *role_query = NULL; apol_vector_t *user_v = NULL, *role_v = NULL; const qpol_user_t *user; const qpol_type_t *type; const qpol_mls_range_t *user_range; apol_mls_range_t *user_apol_range = NULL; int retval = -1, retval2; if (context == NULL) { return 1; } if (context->user != NULL) { if ((user_query = apol_user_query_create()) == NULL) { ERR(p, "%s", strerror(ENOMEM)); } if (apol_user_query_set_user(p, user_query, context->user) < 0 || (context->role != NULL && apol_user_query_set_role(p, user_query, context->role) < 0) || apol_user_get_by_query(p, user_query, &user_v) < 0) { goto cleanup; } if (apol_vector_get_size(user_v) == 0) { retval = 0; goto cleanup; } } if (context->role != NULL) { if ((role_query = apol_role_query_create()) == NULL) { ERR(p, "%s", strerror(ENOMEM)); } if (apol_role_query_set_role(p, role_query, context->role) < 0 || (context->type != NULL && apol_role_query_set_type(p, role_query, context->type) < 0) || apol_role_get_by_query(p, role_query, &role_v) < 0) { goto cleanup; } if (apol_vector_get_size(role_v) == 0) { retval = 0; goto cleanup; } } if (context->type != NULL) { if (qpol_policy_get_type_by_name(p->p, context->type, &type) < 0) { retval = 0; goto cleanup; } } if (apol_policy_is_mls(p) && context->range != NULL) { retval2 = apol_mls_range_validate(p, context->range); if (retval2 != 1) { retval = retval2; goto cleanup; } /* next check that the user has access to this context */ if (context->user != NULL) { if (qpol_policy_get_user_by_name(p->p, context->user, &user) < 0 || qpol_user_get_range(p->p, user, &user_range) < 0) { goto cleanup; } user_apol_range = apol_mls_range_create_from_qpol_mls_range(p, user_range); if (user_apol_range == NULL) { ERR(p, "%s", strerror(ENOMEM)); goto cleanup; } retval2 = apol_mls_range_compare(p, user_apol_range, context->range, APOL_QUERY_SUB); if (retval2 != 1) { retval = retval2; goto cleanup; } } } retval = 1; cleanup: apol_user_query_destroy(&user_query); apol_role_query_destroy(&role_query); apol_vector_destroy(&user_v); apol_vector_destroy(&role_v); apol_mls_range_destroy(&user_apol_range); return retval; }
apol_mls_range_t *apol_mls_range_create_from_string(const apol_policy_t * p, const char *mls_range_string) { if (p == NULL || mls_range_string == NULL) { ERR(p, "%s", strerror(EINVAL)); errno = EINVAL; return NULL; } apol_mls_range_t *r = apol_mls_range_create(); if (r == NULL) { ERR(p, "%s", strerror(errno)); return NULL; } char *dash; if ((dash = strchr(mls_range_string, '-')) == NULL) { // just a low level apol_mls_level_t *l = apol_mls_level_create_from_string(p, mls_range_string); if (l == NULL) { ERR(p, "%s", strerror(errno)); apol_mls_range_destroy(&r); return NULL; } r->low = l; } else { // both a low and a high level if (dash == mls_range_string) { apol_mls_range_destroy(&r); ERR(p, "%s", strerror(EINVAL)); errno = EINVAL; return NULL; } char *s = strndup(mls_range_string, dash - mls_range_string); if (s == NULL) { ERR(p, "%s", strerror(errno)); apol_mls_range_destroy(&r); return NULL; } apol_mls_level_t *l = apol_mls_level_create_from_string(p, s); if (l == NULL) { ERR(p, "%s", strerror(errno)); apol_mls_range_destroy(&r); free(s); return NULL; } r->low = l; free(s); l = NULL; if ((l = apol_mls_level_create_from_string(p, dash + 1)) == NULL) { ERR(p, "%s", strerror(errno)); apol_mls_range_destroy(&r); return NULL; } r->high = l; } if (apol_mls_range_validate(p, r) <= 0) { ERR(p, "%s", strerror(EINVAL)); errno = EINVAL; apol_mls_range_destroy(&r); return NULL; } return r; }