Пример #1
0
/**
 * Compare two qpol_level_datum_t objects.
 * This function is meant to be passed to apol_vector_compare
 * as the callback for performing comparisons.
 *
 * @param datum1 Reference to a qpol_level_datum_t object
 * @param datum2 Reference to a qpol_level_datum_t object
 * @param data Reference to a policy
 * @return Greater than 0 if the first argument is less than the second argument,
 * less than 0 if the first argument is greater than the second argument,
 * 0 if the arguments are equal
 */
static int qpol_level_datum_compare(const void *datum1, const void *datum2, void *data)
{
	const qpol_level_t *lvl_datum1 = NULL, *lvl_datum2 = NULL;
	apol_policy_t *policydb = NULL;
	qpol_policy_t *q;
	uint32_t val1, val2;

	policydb = (apol_policy_t *) data;
	assert(policydb);
	q = apol_policy_get_qpol(policydb);

	if (!datum1 || !datum2)
		goto exit_err;
	lvl_datum1 = datum1;
	lvl_datum2 = datum2;

	if (qpol_level_get_value(q, lvl_datum1, &val1))
		goto exit_err;
	if (qpol_level_get_value(q, lvl_datum2, &val2))
		goto exit_err;

	return (val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);

      exit_err:
	assert(0);
	return 0;
}
Пример #2
0
static int mls_range_comp(const void *a, const void *b, void *data)
{
	const apol_mls_level_t *l1 = a;
	const apol_mls_level_t *l2 = b;
	qpol_policy_t *q = (qpol_policy_t *) data;
	const qpol_level_t *l;
	uint32_t low_value, high_value;
	qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(l1), &l);
	qpol_level_get_value(q, l, &low_value);
	qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(l2), &l);
	qpol_level_get_value(q, l, &high_value);
	assert(low_value != 0 && high_value != 0);
	return low_value - high_value;
}
Пример #3
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;
}