void nomls_tests() { size_t first_diff = 0; int test_result; unchanged_users_v = apol_vector_create(free); changed_users_v = apol_vector_create(free); apol_vector_t *correct_unchanged_users_v = string_array_to_vector(nomls_unchanged_users); apol_vector_t *correct_changed_users_v = string_array_to_vector(nomls_changed_users); build_nomls_vecs(); apol_vector_sort(unchanged_users_v, compare_str, NULL); apol_vector_sort(correct_unchanged_users_v, compare_str, NULL); CU_ASSERT_FALSE(test_result = apol_vector_compare(unchanged_users_v, correct_unchanged_users_v, compare_str, NULL, &first_diff)); if (test_result) { print_test_failure(unchanged_users_v, correct_unchanged_users_v, first_diff, "Unchanged MLS Users"); } apol_vector_sort(changed_users_v, compare_str, NULL); apol_vector_sort(correct_changed_users_v, compare_str, NULL); CU_ASSERT_FALSE(test_result = apol_vector_compare(changed_users_v, correct_changed_users_v, compare_str, NULL, &first_diff)); if (test_result) { print_test_failure(changed_users_v, correct_changed_users_v, first_diff, "Changed MLS Users"); } apol_vector_destroy(&unchanged_users_v); apol_vector_destroy(&changed_users_v); apol_vector_destroy(&correct_unchanged_users_v); apol_vector_destroy(&correct_changed_users_v); }
int level_deep_diff(poldiff_t * diff, const void *x, const void *y) { const qpol_level_t *l1 = x; const qpol_level_t *l2 = y; apol_vector_t *v1 = NULL, *v2 = NULL; apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL; const char *name; poldiff_level_t *l = NULL; int retval = -1, error = 0, compval; if (qpol_level_get_name(diff->orig_qpol, l1, &name) < 0 || (v1 = level_get_cats(diff, diff->orig_pol, l1)) == NULL || (v2 = level_get_cats(diff, diff->mod_pol, l2)) == NULL) { error = errno; goto cleanup; } apol_vector_sort(v1, apol_str_strcmp, NULL); apol_vector_sort(v2, apol_str_strcmp, NULL); compval = level_deep_diff_cats(diff, v1, v2, &added, &removed, &unmodified); if (compval < 0) { error = errno; goto cleanup; } else if (compval > 0) { if ((l = make_diff(diff, POLDIFF_FORM_MODIFIED, name)) == NULL) { error = errno; goto cleanup; } apol_vector_destroy(&l->added_cats); apol_vector_destroy(&l->removed_cats); apol_vector_destroy(&l->unmodified_cats); if ((l->added_cats = apol_vector_create_from_vector(added, apol_str_strdup, NULL, free)) == NULL || (l->removed_cats = apol_vector_create_from_vector(removed, apol_str_strdup, NULL, free)) == NULL || (l->unmodified_cats = apol_vector_create_from_vector(unmodified, apol_str_strdup, NULL, free)) == NULL) { error = errno; ERR(diff, "%s", strerror(error)); goto cleanup; } apol_vector_sort(l->removed_cats, level_cat_comp, diff->orig_qpol); apol_vector_sort(l->added_cats, level_cat_comp, diff->mod_qpol); apol_vector_sort(l->unmodified_cats, level_cat_comp, diff->orig_qpol); if (apol_vector_append(diff->level_diffs->diffs, l) < 0) { error = errno; ERR(diff, "%s", strerror(error)); goto cleanup; } diff->level_diffs->num_modified++; } retval = 0; cleanup: apol_vector_destroy(&v1); apol_vector_destroy(&v2); apol_vector_destroy(&added); apol_vector_destroy(&removed); apol_vector_destroy(&unmodified); if (retval != 0) { level_free(l); } errno = error; return retval; }
/** * Gets a textual representation of a MLS category and * all of that category's sensitivies. * * @param type_datum Reference to sepol type_datum * @param policydb Reference to a policy */ static PyObject* get_cat_sens(const qpol_cat_t * cat_datum, const apol_policy_t * policydb) { const char *cat_name, *lvl_name; apol_level_query_t *query = NULL; apol_vector_t *v = NULL; const qpol_level_t *lvl_datum = NULL; qpol_policy_t *q = apol_policy_get_qpol(policydb); size_t i, n_sens = 0; int error = 0; PyObject *list = NULL; PyObject *dict = PyDict_New(); if (!dict) goto err; if (!cat_datum || !policydb) goto err; /* get category name for apol query */ if (qpol_cat_get_name(q, cat_datum, &cat_name)) goto cleanup; query = apol_level_query_create(); if (!query) goto err; if (apol_level_query_set_cat(policydb, query, cat_name)) goto err; if (apol_level_get_by_query(policydb, query, &v)) goto err; apol_vector_sort(v, &qpol_level_datum_compare, (void *)policydb); dict = PyDict_New(); if (!dict) goto err; if (py_insert_string(dict, "name", cat_name)) goto err; n_sens = apol_vector_get_size(v); list = PyList_New(0); if (!list) goto err; for (i = 0; i < n_sens; i++) { lvl_datum = (qpol_level_t *) apol_vector_get_element(v, i); if (!lvl_datum) goto err; if (qpol_level_get_name(q, lvl_datum, &lvl_name)) goto err; if (py_append_string(list, lvl_name)) goto err; } if (py_insert_obj(dict, "level", list)) goto err; Py_DECREF(list); goto cleanup; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(errno)); py_decref(list); list = NULL; py_decref(dict); dict = NULL; cleanup: apol_level_query_destroy(&query); apol_vector_destroy(&v); errno = error; return dict; }
/** * Prints statistics regarding a policy's MLS categories. * If this function is given a name, it will attempt to * get statistics about a particular category; otherwise * the function gets statistics about all of the policy's * categories. * * @param name Reference to a MLS category's name; if NULL, * all categories will be considered * @param policydb Reference to a policy * * @return 0 on success, < 0 on error. */ static PyObject* get_cats(const char *name, const apol_policy_t * policydb) { PyObject *obj = NULL; apol_cat_query_t *query = NULL; apol_vector_t *v = NULL; const qpol_cat_t *cat_datum = NULL; size_t i, n_cats; int error = 0; int rt; PyObject *list = PyList_New(0); if (!list) goto err; query = apol_cat_query_create(); if (!query) goto err; if (apol_cat_query_set_cat(policydb, query, name)) goto err; if (apol_cat_get_by_query(policydb, query, &v)) goto err; n_cats = apol_vector_get_size(v); apol_vector_sort(v, &qpol_cat_datum_compare, (void *)policydb); for (i = 0; i < n_cats; i++) { cat_datum = apol_vector_get_element(v, i); if (!cat_datum) goto err; obj = get_cat_sens(cat_datum, policydb); if (!obj) goto err; rt = py_append_obj(list, obj); Py_DECREF(obj); if (rt) goto err; } if (name && !n_cats) { goto err; } goto cleanup; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(errno)); py_decref(list); list = NULL; cleanup: apol_cat_query_destroy(&query); apol_vector_destroy(&v); errno = error; return list; }
apol_vector_t *level_get_items(poldiff_t * diff, const apol_policy_t * policy) { qpol_iterator_t *iter = NULL; apol_vector_t *v = NULL; qpol_policy_t *q = apol_policy_get_qpol(policy); int error = 0; if (qpol_policy_get_level_iter(q, &iter) < 0) { return NULL; } v = apol_vector_create_from_iter(iter, NULL); if (v == NULL) { error = errno; ERR(diff, "%s", strerror(error)); qpol_iterator_destroy(&iter); errno = error; return NULL; } qpol_iterator_destroy(&iter); apol_vector_sort(v, level_name_comp, (void *)policy); return v; }
int level_deep_diff_apol_mls_levels(poldiff_t * diff, const apol_mls_level_t * level1, const apol_mls_level_t * level2, poldiff_level_t ** orig_pl, poldiff_level_t ** mod_pl) { poldiff_level_t *u1 = NULL, *u2 = NULL; apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL; const char *sens1 = apol_mls_level_get_sens(level1); const apol_vector_t *cats1 = apol_mls_level_get_cats(level1); const char *sens2 = apol_mls_level_get_sens(level2); const apol_vector_t *cats2 = apol_mls_level_get_cats(level2); int retval = -1, compval; *orig_pl = *mod_pl = NULL; if (strcmp(sens1, sens2) != 0) { /* sensitivities do not match, so don't check categories */ if ((u1 = make_diff(diff, POLDIFF_FORM_REMOVED, sens1)) == NULL || (u2 = make_diff(diff, POLDIFF_FORM_ADDED, sens2)) == NULL) { ERR(diff, "%s", strerror(errno)); level_free(u1); level_free(u2); return -1; } apol_vector_destroy(&u1->removed_cats); apol_vector_destroy(&u2->added_cats); if ((u1->removed_cats = apol_vector_create_from_vector(cats1, apol_str_strdup, NULL, free)) == NULL || (u2->added_cats = apol_vector_create_from_vector(cats2, apol_str_strdup, NULL, free)) == NULL) { ERR(diff, "%s", strerror(errno)); level_free(u1); level_free(u2); return -1; } apol_vector_sort(u1->removed_cats, level_cat_comp, diff->orig_qpol); apol_vector_sort(u2->added_cats, level_cat_comp, diff->mod_qpol); *orig_pl = u1; *mod_pl = u2; return 0; } compval = level_deep_diff_cats(diff, cats1, cats2, &added, &removed, &unmodified); if (compval < 0) { goto cleanup; } else if (compval > 0) { if ((u1 = calloc(1, sizeof(*u1))) == NULL || (u1->name = strdup(sens1)) == NULL || (u1->added_cats = apol_vector_create_from_vector(added, apol_str_strdup, NULL, free)) == NULL || (u1->removed_cats = apol_vector_create_from_vector(removed, apol_str_strdup, NULL, free)) == NULL || (u1->unmodified_cats = apol_vector_create_from_vector(unmodified, apol_str_strdup, NULL, free)) == NULL) { ERR(diff, "%s", strerror(errno)); level_free(u1); goto cleanup; } apol_vector_sort(u1->added_cats, level_cat_comp, diff->mod_qpol); apol_vector_sort(u1->removed_cats, level_cat_comp, diff->orig_qpol); apol_vector_sort(u1->unmodified_cats, level_cat_comp, diff->orig_qpol); u1->form = POLDIFF_FORM_MODIFIED; *orig_pl = u1; } retval = 0; cleanup: apol_vector_destroy(&added); apol_vector_destroy(&removed); apol_vector_destroy(&unmodified); return retval; }
apol_vector_t *apol_mls_range_get_levels(const apol_policy_t * p, const apol_mls_range_t * range) { qpol_policy_t *q = apol_policy_get_qpol(p); apol_vector_t *v = NULL, *catv = NULL; const qpol_level_t *l; uint32_t low_value, high_value, value; int error = 0; qpol_iterator_t *iter = NULL, *catiter = NULL; if (p == NULL || range == NULL || range->low == NULL) { error = EINVAL; ERR(p, "%s", strerror(error)); goto err; } apol_mls_level_t *low_level, *high_level; low_level = range->low; if (range->high == NULL) { high_level = low_level; } else { high_level = range->high; } if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(low_level), &l) < 0 || qpol_level_get_value(q, l, &low_value) < 0) { error = errno; goto err; } if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(high_level), &l) < 0 || qpol_level_get_value(q, l, &high_value) < 0) { error = errno; goto err; } assert(low_value <= high_value); if ((v = apol_vector_create(mls_level_free)) == NULL) { error = errno; ERR(p, "%s", strerror(error)); goto err; } if (qpol_policy_get_level_iter(q, &iter) < 0) { error = errno; goto err; } for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { const char *name; apol_mls_level_t *ml; if (qpol_iterator_get_item(iter, (void **)&l) < 0 || qpol_level_get_value(q, l, &value) < 0 || qpol_level_get_name(q, l, &name) < 0) { error = errno; goto err; } if (value < low_value || value > high_value) { continue; } if ((ml = apol_mls_level_create()) == NULL || (apol_mls_level_set_sens(p, ml, name) < 0)) { error = errno; apol_mls_level_destroy(&ml); ERR(p, "%s", strerror(error)); goto err; } if (qpol_level_get_cat_iter(q, l, &catiter) < 0 || (catv = apol_vector_create_from_iter(catiter, NULL)) == NULL) { error = errno; goto err; } const apol_vector_t *high_cats = apol_mls_level_get_cats(high_level); for (size_t i = 0; i < apol_vector_get_size(high_cats); i++) { char *cat_name = apol_vector_get_element(high_cats, i); size_t j; /* do not add categories that are not members of the level */ if (apol_vector_get_index(catv, cat_name, mls_level_name_to_cat_comp, q, &j) < 0) { /* this category is not legal under the given policy */ continue; } if (apol_mls_level_append_cats(p, ml, cat_name) < 0) { error = errno; apol_mls_level_destroy(&ml); ERR(p, "%s", strerror(error)); goto err; } } qpol_iterator_destroy(&catiter); apol_vector_destroy(&catv); if (apol_vector_append(v, ml) < 0) { error = errno; apol_mls_level_destroy(&ml); ERR(p, "%s", strerror(error)); goto err; } } apol_vector_sort(v, mls_range_comp, q); qpol_iterator_destroy(&iter); qpol_iterator_destroy(&catiter); apol_vector_destroy(&catv); return v; err: qpol_iterator_destroy(&iter); qpol_iterator_destroy(&catiter); apol_vector_destroy(&v); apol_vector_destroy(&catv); errno = error; return NULL; }