int qpol_user_get_range(const qpol_policy_t * policy, const qpol_user_t * datum, const qpol_mls_range_t ** range) { user_datum_t *internal_datum = NULL; if (policy == NULL || datum == NULL || range == NULL) { if (range != NULL) *range = NULL; ERR(policy, "%s", strerror(EINVAL)); errno = EINVAL; return STATUS_ERR; } if (!qpol_policy_has_capability(policy, QPOL_CAP_MLS)) { *range = NULL; } else { internal_datum = (user_datum_t *) datum; *range = (qpol_mls_range_t *) & internal_datum->exp_range; } return STATUS_SUCCESS; }
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; }
/** * Display a vector of rules (either qpol_avrule_t or * qpol_syn_avrule_t) in the rules text buffer. */ static void policy_view_display_avrule_results(policy_view_t * pv, apol_vector_t * results, int is_syn_rules) { apol_policy_t *policy = toplevel_get_policy(pv->top); qpol_policy_t *qp = apol_policy_get_qpol(policy); GtkTextIter start, end; char *string, buf[64]; size_t i; gtk_text_buffer_get_start_iter(pv->rules_text, &start); gtk_text_buffer_get_end_iter(pv->rules_text, &end); gtk_text_buffer_delete(pv->rules_text, &start, &end); snprintf(buf, 64, "%zd rule(s) match the search criteria.\n\n", apol_vector_get_size(results)); gtk_text_buffer_insert_with_tags_by_name(pv->rules_text, &end, buf, -1, "summary", NULL); for (i = 0; i < apol_vector_get_size(results); i++) { if (!is_syn_rules) { qpol_avrule_t *rule = apol_vector_get_element(results, i); string = apol_avrule_render(policy, rule); } else { qpol_syn_avrule_t *rule = apol_vector_get_element(results, i); string = apol_syn_avrule_render(policy, rule); unsigned long lineno; if (qpol_policy_has_capability(qp, QPOL_CAP_LINE_NUMBERS)) { qpol_syn_avrule_get_lineno(qp, rule, &lineno); sprintf(buf, "%ld", lineno); gtk_text_buffer_insert_with_tags_by_name(pv->rules_text, &end, "[", -1, "rule", NULL); gtk_text_buffer_insert_with_tags_by_name(pv->rules_text, &end, buf, -1, "line-number", NULL); gtk_text_buffer_insert_with_tags_by_name(pv->rules_text, &end, "] ", -1, "rule", NULL); } } if (string == NULL) { toplevel_ERR(pv->top, "Error displaying rule: %s", strerror(errno)); return; } gtk_text_buffer_insert_with_tags_by_name(pv->rules_text, &end, string, -1, "rule", NULL); free(string); gtk_text_buffer_insert(pv->rules_text, &end, "\n", -1); } }
/** * Perform the rule query within a thread. */ static gpointer policy_view_find_terules_runner(gpointer data) { struct find_terules_datum *run = (struct find_terules_datum *)data; run->results = NULL; qpol_policy_t *q = apol_policy_get_qpol(run->policy); if (!qpol_policy_has_capability(q, QPOL_CAP_SYN_RULES)) { progress_update(run->progress, "Searching AV rules"); run->retval = apol_avrule_get_by_query(run->policy, run->query, &run->results); run->is_syn_rules = 0; } else { qpol_policy_build_syn_rule_table(q); progress_update(run->progress, "Searching syntactic AV rules"); run->retval = apol_syn_avrule_get_by_query(run->policy, run->query, &run->results); run->is_syn_rules = 1; } if (run->retval == 0) { progress_done(run->progress); } else { progress_abort(run->progress, NULL); } return NULL; }
PyObject* search(bool allow, bool neverallow, bool auditallow, bool dontaudit, bool transition, bool role_allow, const char *src_name, const char *tgt_name, const char *class_name, const char *permlist ) { options_t cmd_opts; PyObject *output = NULL; apol_vector_t *v = NULL; memset(&cmd_opts, 0, sizeof(cmd_opts)); cmd_opts.indirect = true; cmd_opts.show_cond = true; cmd_opts.allow = allow; cmd_opts.nallow = neverallow; cmd_opts.auditallow = auditallow; cmd_opts.dontaudit = dontaudit; cmd_opts.type = transition; cmd_opts.role_allow = role_allow; if (src_name) cmd_opts.src_name = strdup(src_name); if (tgt_name) cmd_opts.tgt_name = strdup(tgt_name); if (class_name) cmd_opts.class_name = strdup(class_name); if (permlist){ cmd_opts.perm_vector = apol_vector_create(free); cmd_opts.permlist = strdup(permlist); } if (!cmd_opts.semantic && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(policy))) { PyErr_SetString(PyExc_RuntimeError,"Query failed"); goto cleanup; } } /* if syntactic rules are not available always do semantic search */ if (!qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { cmd_opts.semantic = 1; } /* supress line numbers if doing semantic search or not available */ if (cmd_opts.semantic || !qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_LINE_NUMBERS)) { cmd_opts.lineno = 0; } if (perform_av_query(policy, &cmd_opts, &v)) { goto cleanup; } output = PyList_New(0); if (!output) goto cleanup; if (v) { get_av_results(policy, v, output); } apol_vector_destroy(&v); if (perform_te_query(policy, &cmd_opts, &v)) { goto cleanup; } if (v) { get_te_results(policy, v, output); } if (cmd_opts.all || cmd_opts.type) { apol_vector_destroy(&v); if (perform_ft_query(policy, &cmd_opts, &v)) { goto cleanup; } if (v) { get_ft_results(policy, v, output); } } if (cmd_opts.all || cmd_opts.role_allow) { apol_vector_destroy(&v); if (perform_ra_query(policy, &cmd_opts, &v)) { goto cleanup; } if (v) { get_ra_results(policy, v, output); } } apol_vector_destroy(&v); cleanup: free(cmd_opts.src_name); free(cmd_opts.tgt_name); free(cmd_opts.class_name); free(cmd_opts.permlist); free(cmd_opts.bool_name); free(cmd_opts.src_role_name); free(cmd_opts.tgt_role_name); apol_vector_destroy(&cmd_opts.perm_vector); apol_vector_destroy(&cmd_opts.class_vector); if (output && PyList_GET_SIZE(output) == 0) { py_decref(output); return Py_None; } return output; }
static int perform_av_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) { apol_avrule_query_t *avq = NULL; unsigned int rules = 0; int error = 0; char *tmp = NULL, *tok = NULL, *s = NULL; if (!policy || !opt || !v) { PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); errno = EINVAL; return -1; } if (!opt->all && !opt->allow && !opt->nallow && !opt->auditallow && !opt->dontaudit) { *v = NULL; return 0; /* no search to do */ } avq = apol_avrule_query_create(); if (!avq) { PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); errno = ENOMEM; return -1; } if (opt->allow || opt->all) rules |= QPOL_RULE_ALLOW; if (opt->nallow || opt->all) // Add this regardless of policy capabilities rules |= QPOL_RULE_NEVERALLOW; if (opt->auditallow || opt->all) rules |= QPOL_RULE_AUDITALLOW; if (opt->dontaudit || opt->all) rules |= QPOL_RULE_DONTAUDIT; if (rules != 0) // Setting rules = 0 means you want all the rules apol_avrule_query_set_rules(policy, avq, rules); apol_avrule_query_set_regex(policy, avq, opt->useregex); if (opt->src_name) apol_avrule_query_set_source(policy, avq, opt->src_name, opt->indirect); if (opt->tgt_name) apol_avrule_query_set_target(policy, avq, opt->tgt_name, opt->indirect); if (opt->bool_name) apol_avrule_query_set_bool(policy, avq, opt->bool_name); if (opt->class_name) { if (opt->class_vector == NULL) { if (apol_avrule_query_append_class(policy, avq, opt->class_name)) { goto err; } } else { size_t i; for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { char *class_name; class_name = apol_vector_get_element(opt->class_vector, i); if (!class_name) continue; if (apol_avrule_query_append_class(policy, avq, class_name)) { goto err; } } } } if (opt->permlist) { tmp = strdup(opt->permlist); for (tok = strtok(tmp, ","); tok; tok = strtok(NULL, ",")) { if (apol_avrule_query_append_perm(policy, avq, tok)) { goto err; } if ((s = strdup(tok)) == NULL || apol_vector_append(opt->perm_vector, s) < 0) { goto err; } s = NULL; } free(tmp); tmp = NULL; } if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { if (apol_syn_avrule_get_by_query(policy, avq, v)) { goto err; } } else { if (apol_avrule_get_by_query(policy, avq, v)) { goto err; } } apol_avrule_query_destroy(&avq); return 0; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(error)); apol_vector_destroy(v); apol_avrule_query_destroy(&avq); free(tmp); free(s); errno = error; return -1; }
static int perform_te_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) { apol_terule_query_t *teq = NULL; unsigned int rules = 0; int error = 0; size_t i; if (!policy || !opt || !v) { PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); errno = EINVAL; return -1; } if (opt->all || opt->type) { rules = (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER); } else { *v = NULL; return 0; /* no search to do */ } teq = apol_terule_query_create(); if (!teq) { PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); errno = ENOMEM; return -1; } apol_terule_query_set_rules(policy, teq, rules); apol_terule_query_set_regex(policy, teq, opt->useregex); if (opt->src_name) apol_terule_query_set_source(policy, teq, opt->src_name, opt->indirect); if (opt->tgt_name) apol_terule_query_set_target(policy, teq, opt->tgt_name, opt->indirect); if (opt->bool_name) apol_terule_query_set_bool(policy, teq, opt->bool_name); if (opt->class_name) { if (opt->class_vector == NULL) { if (apol_terule_query_append_class(policy, teq, opt->class_name)) { error = errno; goto err; } } else { for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { char *class_name; class_name = apol_vector_get_element(opt->class_vector, i); if (!class_name) continue; if (apol_terule_query_append_class(policy, teq, class_name)) { error = errno; goto err; } } } } if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { if (apol_syn_terule_get_by_query(policy, teq, v)) { goto err; } } else { if (apol_terule_get_by_query(policy, teq, v)) { goto err; } } apol_terule_query_destroy(&teq); return 0; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(error)); apol_vector_destroy(v); apol_terule_query_destroy(&teq); errno = error; return -1; }
/** * 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; }
bool sechk_lib_check_requirement(sechk_name_value_t * req, sechk_lib_t * lib) { struct stat stat_buf; if (!req) { fprintf(stderr, "Error: invalid requirement\n"); errno = EINVAL; return false; } if (!lib || !lib->policy) { fprintf(stderr, "Error: invalid library\n"); errno = EINVAL; return false; } if (!strcmp(req->name, SECHK_REQ_POLICY_CAP)) { if (!strcmp(req->value, SECHK_REQ_CAP_ATTRIB_NAMES)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_ATTRIB_NAMES)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_MLS)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MLS)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_SYN_RULES)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_SYN_RULES)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_RULES_LOADED)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_RULES_LOADED)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_LINE_NOS)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_LINE_NUMBERS)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_CONDITIONALS)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_CONDITIONALS)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else if (!strcmp(req->value, SECHK_REQ_CAP_MODULES)) { if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MODULES)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); } return false; } } else { ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value); return false; } } else if (!strcmp(req->name, SECHK_REQ_DEFAULT_CONTEXTS)) { #ifdef LIBSELINUX if (stat(selinux_default_context_path(), &stat_buf) < 0) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s not met.", req->name); } return false; } #else if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Checking requirement %s: %s", req->name, strerror(ENOTSUP)); } return false; #endif } else if (!strcmp(req->name, SECHK_REQ_FILE_CONTEXTS)) { if (!lib->fc_entries || !apol_vector_get_size(lib->fc_entries)) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) { ERR(lib->policy, "Requirement %s not met.", req->name); } } } else if (!strcmp(req->name, SECHK_REQ_SYSTEM)) { if (!strcmp(req->value, SECHK_REQ_SYS_SELINUX)) { #ifdef LIBSELINUX if (!is_selinux_mls_enabled() || !is_selinux_enabled()) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); return false; } #else if (lib->outputformat & ~(SECHK_OUT_QUIET)) ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP)); return false; #endif } else if (!strcmp(req->value, SECHK_REQ_SYS_MLS)) { #ifdef LIBSELINUX if (!is_selinux_mls_enabled() || !is_selinux_enabled()) { if (lib->outputformat & ~(SECHK_OUT_QUIET)) ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value); return false; } #else if (lib->outputformat & ~(SECHK_OUT_QUIET)) ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP)); return false; #endif } else { ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value); return false; } } else { ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value); return false; } return true; }