Example #1
0
int level_comp(const void *x, const void *y, const poldiff_t * diff)
{
	const qpol_level_t *l1 = x;
	const qpol_level_t *l2 = y;
	const char *name1, *name2;
	if (qpol_level_get_name(diff->orig_qpol, l1, &name1) < 0 || qpol_level_get_name(diff->mod_qpol, l2, &name2) < 0) {
		return 0;
	}
	return strcmp(name1, name2);
}
Example #2
0
/**
 * Comparison function for two levels from the same policy.
 */
static int level_name_comp(const void *x, const void *y, void *arg)
{
	const qpol_level_t *s1 = x;
	const qpol_level_t *s2 = y;
	apol_policy_t *p = arg;
	qpol_policy_t *q = apol_policy_get_qpol(p);
	const char *name1, *name2;

	if (qpol_level_get_name(q, s1, &name1) < 0 || qpol_level_get_name(q, s2, &name2) < 0)
		return 0;
	return strcmp(name1, name2);
}
Example #3
0
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;
}
Example #4
0
int level_new_diff(poldiff_t * diff, poldiff_form_e form, const void *item)
{
	const qpol_level_t *l = item;
	const char *name = NULL;
	poldiff_level_t *pl = NULL;
	apol_policy_t *p;
	qpol_policy_t *q;
	apol_vector_t *v = NULL;
	int error = 0, retval = -1;
	if (form == POLDIFF_FORM_ADDED) {
		p = diff->mod_pol;
		q = diff->mod_qpol;
	} else {
		p = diff->orig_pol;
		q = diff->orig_qpol;
	}
	if (qpol_level_get_name(q, l, &name) < 0 || (pl = make_diff(diff, form, name)) == NULL) {
		error = errno;
		goto cleanup;
	}
	if ((v = level_get_cats(diff, p, l)) == NULL) {
		error = errno;
		ERR(diff, "%s", strerror(error));
		goto cleanup;
	}
	if (form == POLDIFF_FORM_ADDED) {
		apol_vector_destroy(&pl->added_cats);
		if ((pl->added_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
	} else if (form == POLDIFF_FORM_REMOVED) {
		apol_vector_destroy(&pl->removed_cats);
		if ((pl->removed_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
	}
	if (apol_vector_append(diff->level_diffs->diffs, pl) < 0) {
		error = errno;
		ERR(diff, "%s", strerror(error));
		goto cleanup;
	}
	if (form == POLDIFF_FORM_ADDED) {
		diff->level_diffs->num_added++;
	} else {
		diff->level_diffs->num_removed++;
	}
	retval = 0;
      cleanup:
	apol_vector_destroy(&v);
	if (retval < 0) {
		level_free(pl);
		errno = error;
	}
	return retval;
}
Example #5
0
/**
 * 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;
}
Example #6
0
/**
 * Get a policy's MLS sensitivities.
 * If this function is given a name, it will attempt to
 * get statistics about a particular sensitivity; otherwise
 * the function gets statistics about all of the policy's
 * sensitivities.
 *
 * @param name Reference to a sensitivity's name; if NULL,
 * all sensitivities will be considered
 * @param policydb Reference to a policy
 *
 * @return 0 on success, < 0 on error.
 */
static PyObject* get_sens(const char *name, const apol_policy_t * policydb)
{
	PyObject *dict = NULL;
	int error = 0;
	int rt = 0;
	size_t i;
	char *tmp = NULL;
	const char *lvl_name = NULL;
	apol_level_query_t *query = NULL;
	apol_vector_t *v = NULL;
	const qpol_level_t *level = NULL;
	apol_mls_level_t *ap_mls_lvl = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);

	query = apol_level_query_create();
	if (!query)
		goto cleanup;
	if (apol_level_query_set_sens(policydb, query, name))
		goto cleanup;
	if (apol_level_get_by_query(policydb, query, &v))
		goto cleanup;

	dict = PyDict_New();
	if (!dict) goto err;
	for (i = 0; i < apol_vector_get_size(v); i++) {
		level = apol_vector_get_element(v, i);
		if (qpol_level_get_name(q, level, &lvl_name))
			goto err;
		ap_mls_lvl = (apol_mls_level_t *) apol_mls_level_create_from_qpol_level_datum(policydb, level);
		tmp = apol_mls_level_render(policydb, ap_mls_lvl);
		apol_mls_level_destroy(&ap_mls_lvl);
		if (!tmp)
			goto cleanup;
		if (py_insert_string(dict, lvl_name, tmp))
			goto err;
		free(tmp); tmp = NULL;
		if (rt) goto err;
	}

	if (name && !apol_vector_get_size(v)) {
		goto cleanup;
	}

	goto cleanup;
err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(error));
	py_decref(dict); dict = NULL;
cleanup:
	free(tmp);
	apol_level_query_destroy(&query);
	apol_vector_destroy(&v);
	errno = error;
	return dict;
}
Example #7
0
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;
}