Esempio n. 1
0
/**
 * Get statistics regarding a policy's roles.
 * If this function is given a name, it will attempt to
 * get statistics about a particular role; otherwise
 * the function get statistics about all of the policy's roles.
 *
 * @param name Reference to an role's name; if NULL,
 * all roles will be considered
 * @param policydb Reference to a policy
 *
 * @return 0 on success, < 0 on error.
 */
static PyObject*  get_roles(const char *name, const apol_policy_t * policydb)
{
	const qpol_role_t *role_datum = NULL;
	qpol_iterator_t *iter = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	int error = 0;
	int rt;
	PyObject *obj;
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	if (name != NULL) {
		if (qpol_policy_get_role_by_name(q, name, &role_datum)) {
			errno = EINVAL;
			goto err;
		}
		obj = get_role(role_datum, policydb);
		rt = py_append_obj(list, obj);
		Py_DECREF(obj); 
		if (rt) goto err;
	} else {
		if (qpol_policy_get_role_iter(q, &iter))
			goto err;

		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&role_datum))
				goto err;
			obj = get_role(role_datum, policydb);
			rt = py_append_obj(list, obj);
			Py_DECREF(obj); 
			if (rt) goto err;
		}
		qpol_iterator_destroy(&iter);
	}
	goto cleanup;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
	py_decref(list); list = NULL;

cleanup:
	qpol_iterator_destroy(&iter);
	errno = error;
	return list;
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
static PyObject* get_av_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
{
	PyObject *obj, *dict=NULL;
	PyObject *permlist = NULL;
	PyObject *boollist = NULL;
	uint32_t rule_type = 0;
	int rt;
	int error = 0;
	qpol_policy_t *q;
	size_t i, num_rules = 0;
	const qpol_avrule_t *rule = NULL;
	char *tmp = NULL, *rule_str = NULL;
	qpol_cond_expr_node_t *expr = NULL;
	qpol_iterator_t *iter = NULL;
	const qpol_cond_t *cond = NULL;
	uint32_t enabled = 0;
	const qpol_type_t *type;
	const char *tmp_name;
	const qpol_class_t *obj_class = NULL;

	if (!policy || !v) {
		errno = EINVAL;
		goto err;
	}

	if (!(num_rules = apol_vector_get_size(v)))
		return NULL;

	q = apol_policy_get_qpol(policy);

	for (i = 0; i < num_rules; i++) {
		if (!(rule = apol_vector_get_element(v, i)))
			goto err;

		dict = PyDict_New();
		if (!dict) goto err;

		if (qpol_avrule_get_rule_type(q, rule, &rule_type))
			goto err;

		if (!(tmp_name = apol_rule_type_to_str(rule_type))) {
			PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string");
			errno = EINVAL;
			goto err;
		}

		if (py_insert_string(dict, "type", tmp_name))
			goto err;

		if (qpol_avrule_get_source_type(q, rule, &type)) {
			goto err;
		}

		if (qpol_type_get_name(q, type, &tmp_name)) {
			goto err;
		}

		if (py_insert_string(dict, "source", tmp_name))
			goto err;

		if (qpol_avrule_get_target_type(q, rule, &type)) {
			goto err;
		}
		if (qpol_type_get_name(q, type, &tmp_name)) {
			goto err;
		}

		if (py_insert_string(dict, "target", tmp_name))
			goto err;

		if (qpol_avrule_get_object_class(q, rule, &obj_class)) {
			goto err;
		}
		if (qpol_class_get_name(q, obj_class, &tmp_name)) {
			goto err;
		}

		if (py_insert_string(dict, "class", tmp_name))
			goto err;

		if (qpol_avrule_get_perm_iter(q, rule, &iter)) {
			goto err;
		}

		permlist = PyList_New(0);
		if (! permlist) goto err;

		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			const char *perm_name = NULL;
			if (qpol_iterator_get_item(iter, (void **)&perm_name))
				goto err;
			if (py_append_string(permlist, perm_name))
				goto err;
		}

		rt = PyDict_SetItemString(dict, "permlist", permlist);
		py_decref(permlist); permlist=NULL;
		if (rt) goto err;

		if (qpol_avrule_get_cond(q, rule, &cond))
			goto err;
		if (qpol_avrule_get_is_enabled(q, rule, &enabled))
			goto err;

		obj = PyBool_FromLong(enabled);
		rt = PyDict_SetItemString(dict, "enabled", obj);
		py_decref(obj);

		if (cond) {
			obj = get_bool(q, cond, enabled);
			if (!obj) goto err;
			rt = PyDict_SetItemString(dict, "boolean", obj);
			py_decref(obj);
		}

		rt = py_append_obj(output, dict);
		py_decref(dict); dict=NULL;
		if (rt) goto err;

		free(rule_str);	rule_str = NULL;
		free(expr); expr = NULL;
	}
	goto cleanup;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
	py_decref(dict);
	py_decref(permlist);
	py_decref(boollist);

cleanup:
	free(tmp);
	free(rule_str);
	free(expr);
	errno = error;
	return output;
}
Esempio n. 4
0
static PyObject* get_ft_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *list)
{
	PyObject *dict = NULL;
	size_t i, num_filename_trans = 0;
	const char *tmp_name;
	int error = 0;
	int rt;
	const qpol_filename_trans_t *filename_trans = NULL;
	const qpol_class_t *obj_class = NULL;
	char *tmp = NULL, *filename_trans_str = NULL, *expr = NULL;
	qpol_policy_t *q;
	const qpol_type_t *type = NULL;

	if (!policy || !v) {
		errno = EINVAL;
		goto err;
	}

	if (!(num_filename_trans = apol_vector_get_size(v)))
		return NULL;

	q = apol_policy_get_qpol(policy);

	for (i = 0; i < num_filename_trans; i++) {
		if (!(filename_trans = apol_vector_get_element(v, i)))
			goto err;

		dict = PyDict_New();
		if (!dict) goto err;

		if (py_insert_string(dict, "type", "type_transition"))
			goto err;

		/* source type */
		if (qpol_filename_trans_get_source_type(q, filename_trans, &type)) {
			goto err;
		}
		if (qpol_type_get_name(q, type, &tmp_name)) {
			goto err;
		}

		if (py_insert_string(dict, "source", tmp_name))
			goto err;

		if (qpol_filename_trans_get_target_type(q, filename_trans, &type))
			goto err;

		if (qpol_type_get_name(q, type, &tmp_name))
			goto err;

		if (py_insert_string(dict, "target", tmp_name))
			goto err;

		if (qpol_filename_trans_get_object_class(q, filename_trans, &obj_class))
			goto err;

		if (qpol_class_get_name(q, obj_class, &tmp_name))
			goto err;

		if (py_insert_string(dict, "class", tmp_name))
			goto err;

		if (qpol_filename_trans_get_default_type(q, filename_trans, &type))
			goto err;
		if (qpol_type_get_name(q, type, &tmp_name))
			goto err;
		if (py_insert_string(dict, "transtype", tmp_name))
			goto err;

		if (! qpol_filename_trans_get_filename(q, filename_trans, &tmp_name)) {
			if (py_insert_string(dict, "filename", tmp_name))
				goto err;
		}

		rt = py_append_obj(list, dict);
		dict = NULL;
		if (rt) goto err;

		free(filename_trans_str); filename_trans_str = NULL;
		free(expr); expr = NULL;
	}
	goto cleanup;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
	py_decref(dict);
cleanup:
	free(tmp);
	free(filename_trans_str);
	free(expr);
	errno = error;
	return list;
}
Esempio n. 5
0
static PyObject* get_te_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
{
	int error = 0;
	int rt = 0;
	PyObject *obj, *dict=NULL, *tuple = NULL;
	qpol_policy_t *q;
	uint32_t rule_type = 0;
	const qpol_type_t *type;
	size_t i, num_rules = 0;
	const qpol_terule_t *rule = NULL;
	char *tmp = NULL, *rule_str = NULL, *expr = NULL;
	const qpol_cond_t *cond = NULL;
	uint32_t enabled = 0;
	const char *tmp_name;
	const qpol_class_t *obj_class = NULL;

	if (!policy || !v) {
		errno = EINVAL;
		goto err;
	}

	if (!(num_rules = apol_vector_get_size(v)))
		return NULL;

	q = apol_policy_get_qpol(policy);

	for (i = 0; i < num_rules; i++) {
		dict = PyDict_New();
		if (!dict) goto err;
		if (!(rule = apol_vector_get_element(v, i)))
			goto err;
		if (qpol_terule_get_cond(q, rule, &cond))
			goto err;
		if (qpol_terule_get_is_enabled(q, rule, &enabled))
			goto err;

		if (cond) {
			obj = get_bool(q, cond, enabled);
			if (!obj) goto err;
			rt = PyDict_SetItemString(dict, "boolean", obj);
			py_decref(obj);
		}

		if (qpol_terule_get_rule_type(q, rule, &rule_type))
			goto err;

		if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
			PyErr_SetString(PyExc_RuntimeError,"Invalid TE rule type");
			errno = EINVAL;
			goto err;
		}
		if (!(tmp_name = apol_rule_type_to_str(rule_type))) {
			PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string");
			errno = EINVAL;
			goto err;
		}

		if (py_insert_string(dict, "type", tmp_name))
			goto err;

		if (qpol_terule_get_source_type(q, rule, &type))
			goto err;
		if (qpol_type_get_name(q, type, &tmp_name))
			goto err;
		if (py_insert_string(dict, "source", tmp_name))
			goto err;

		if (qpol_terule_get_target_type(q, rule, &type))
			goto err;
		if (qpol_type_get_name(q, type, &tmp_name))
			goto err;
		if (py_insert_string(dict, "target", tmp_name))
			goto err;

		if (qpol_terule_get_object_class(q, rule, &obj_class))
			goto err;
		if (qpol_class_get_name(q, obj_class, &tmp_name))
			goto err;
		if (py_insert_string(dict, "class", tmp_name))
			goto err;

		if (qpol_terule_get_default_type(q, rule, &type))
			goto err;
		if (qpol_type_get_name(q, type, &tmp_name))
			goto err;
		if (py_insert_string(dict, "transtype", tmp_name))
			goto err;

		rt = py_append_obj(output, dict);
		dict = NULL;
		if(rt) goto err;

		free(rule_str);	rule_str = NULL;
		free(expr); expr = NULL;
	}
	goto cleanup;

err:
	error = errno;
	py_decref(dict);
	py_decref(tuple);
	PyErr_SetString(PyExc_RuntimeError,strerror(error));
cleanup:
	free(tmp);
	free(rule_str);
	free(expr);
	errno = error;
	return output;
}
Esempio n. 6
0
static PyObject* get_bool(const qpol_policy_t *q, const qpol_cond_t * cond, int enabled)
{
	qpol_iterator_t *iter = NULL;
	qpol_cond_expr_node_t *expr = NULL;
	char *tmp = NULL;
	const char *bool_name = NULL;
	int error = 0;
	uint32_t expr_type = 0;
	qpol_bool_t *cond_bool = NULL;
	PyObject *obj, *tuple = NULL;
	PyObject *boollist = NULL;

	if (!q || !cond) {
		errno = EINVAL;
		return NULL;
	}
	if (qpol_cond_get_expr_node_iter(q, cond, &iter) < 0) {
		goto err;
	}

	boollist = PyList_New(0);
	if (! boollist) goto err;

	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		if (qpol_iterator_get_item(iter, (void **)&expr)) {
			goto err;
		}
		if (qpol_cond_expr_node_get_expr_type(q, expr, &expr_type)) {
			goto err;
		}
		if (expr_type != QPOL_COND_EXPR_BOOL) {
			obj = PyUnicode_FromString(apol_cond_expr_type_to_str(expr_type));
			if (!obj) goto err;
			if (py_append_obj(boollist, obj))
				goto err;
		} else {
			tuple = PyTuple_New(2);
			if (!tuple) goto err;

			if (qpol_cond_expr_node_get_bool(q, expr, &cond_bool)) {
				goto err;
			}
			if (qpol_bool_get_name(q, cond_bool, &bool_name)) {
				goto err;
			}
			obj = PyUnicode_FromString(bool_name);
			if (py_tuple_insert_obj(tuple, 0, obj))
				goto err;
			obj = PyBool_FromLong(enabled);
			if (py_tuple_insert_obj(tuple, 1, obj))
				goto err;
			if (py_append_obj(boollist, tuple)) 
				goto err;
			tuple=NULL;
		}
	}

	qpol_iterator_destroy(&iter);
	return boollist;

      err:
	error = errno;
	qpol_iterator_destroy(&iter);
	py_decref(tuple);
	py_decref(boollist);
	free(tmp);
	errno = error;
	return NULL;
}
Esempio n. 7
0
static PyObject* get_ra_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
{
	size_t i, num_rules = 0;
	qpol_policy_t *q;
	const qpol_role_allow_t *rule = NULL;
	const char *tmp;
	PyObject *obj, *dict=NULL;
	const qpol_role_t *role = NULL;
	int error = 0;
	errno = EINVAL;
	int rt;

	if (!policy || !v) {
		errno = EINVAL;
		goto err;
	}

	if (!(num_rules = apol_vector_get_size(v)))
		return NULL;

	q = apol_policy_get_qpol(policy);

	for (i = 0; i < num_rules; i++) {
		dict = PyDict_New();
		if (!dict) goto err;
		if (!(rule = apol_vector_get_element(v, i)))
			goto err;

		if (qpol_role_allow_get_source_role(q, rule, &role)) {
			goto err;
		}
		if (qpol_role_get_name(q, role, &tmp)) {
			goto err;
		}
		obj = PyUnicode_FromString(tmp);
		if (py_insert_obj(dict, "source", obj))
			goto err;

		if (qpol_role_allow_get_target_role(q, rule, &role)) {
			goto err;
		}
		if (qpol_role_get_name(q, role, &tmp)) {
			goto err;
		}
		obj = PyUnicode_FromString(tmp);
		if (py_insert_obj(dict, "target", obj))
			goto err;

		rt = py_append_obj(output, dict);
		if (rt) goto err;
		py_decref(dict); dict=NULL;
	}
	goto cleanup;
err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(error));
	py_decref(dict);

cleanup:
	errno = error;
	return output;
}
Esempio n. 8
0
/**
 * Get statistics regarding a policy's ports.
 * If this function is given a name, it will attempt to
 * get statistics about a particular port; otherwise
 * the function get statistics about all of the policy's ports.
 *
 * @param name Reference to an port's name; if NULL,
 * all ports will be considered
 * @param policydb Reference to a policy
 *
 * @return 0 on success, < 0 on error.
 */
static PyObject*  get_ports(const char *num, const apol_policy_t * policydb)
{
	const qpol_portcon_t *portcon = NULL;
	qpol_iterator_t *iter = NULL;
	uint16_t low_port, high_port;
	uint8_t ocon_proto;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	const qpol_context_t *ctxt = NULL;
	const char *proto_str = NULL;
	const char *type = NULL;
	const apol_mls_range_t *range = NULL;
	char *range_str = NULL;
	apol_context_t *c = NULL;
	int error = 0;
	int rt = 0;
	PyObject *dict = NULL;
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	if (qpol_policy_get_portcon_iter(q, &iter))
		goto err;

	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		if (qpol_iterator_get_item(iter, (void **)&portcon))
			goto err;
		if (qpol_portcon_get_low_port(q, portcon, &low_port))
			goto err;
		if (qpol_portcon_get_high_port(q, portcon, &high_port))
			goto err;
		if (qpol_portcon_get_protocol(q, portcon, &ocon_proto))
			goto err;
		if (num) {
			if (atoi(num) < low_port || atoi(num) > high_port)
				continue;
		}

		if ((ocon_proto != IPPROTO_TCP) &&
		    (ocon_proto != IPPROTO_UDP)) 
			goto err;

		if (qpol_portcon_get_context(q, portcon, &ctxt)) {
			PyErr_SetString(PyExc_RuntimeError, "Could not get for port context.");
			goto err;
		}

		if ((proto_str = apol_protocol_to_str(ocon_proto)) == NULL) {
			PyErr_SetString(PyExc_RuntimeError, "Invalid protocol for port");
			goto err;
		}

		if ((c = apol_context_create_from_qpol_context(policydb, ctxt)) == NULL) {
			goto err;
		}
		
		if((type = apol_context_get_type(c)) == NULL) {
			apol_context_destroy(&c);
			goto err;
		}
			
		dict = PyDict_New(); 
		if (!dict) goto err;
		if (py_insert_string(dict, "type", type))
			goto err;

		if((range = apol_context_get_range(c)) != NULL) {
			range_str = apol_mls_range_render(policydb, range);
			if (range_str == NULL) {
				goto err;
			}
			if (py_insert_string(dict, "range", range_str))
				goto err;
		}

		if (py_insert_string(dict, "protocol", proto_str))
			goto err;

		if (py_insert_long(dict, "high", high_port))
			goto err;

		if (py_insert_long(dict, "low", low_port))
			goto err;

		rt = py_append_obj(list, dict);
		Py_DECREF(dict); dict = 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(range_str);
	apol_context_destroy(&c);
	qpol_iterator_destroy(&iter);
	errno = error;
	return list;
}
Esempio n. 9
0
/**
 * Gets statistics regarding a policy's booleans.
 * If this function is given a name, it will attempt to
 * get statistics about a particular boolean; otherwise
 * the function gets statistics about all of the policy's booleans.
 *
 * @param fp Reference to a file to which to print statistics
 * @param name Reference to a boolean's name; if NULL,
 * all booleans will be considered
 * @param expand Flag indicating whether to print each
 * boolean's default state
 * @param policydb Reference to a policy
 *
 * @return new reference, or NULL (setting an exception)
 */
static PyObject* get_booleans(const char *name, const apol_policy_t * policydb)
{
	PyObject *dict = NULL;
	int error = 0;
	int rt = 0;
	const char *bool_name = NULL;
	int state;
	qpol_bool_t *bool_datum = NULL;
	qpol_iterator_t *iter = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	size_t n_bools = 0;
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	if (name != NULL) {
		if (qpol_policy_get_bool_by_name(q, name, &bool_datum))
			goto err;
		if (qpol_bool_get_state(q, bool_datum, &state))
			goto err;

		dict = PyDict_New(); 
		if (!dict) goto err;
		if (py_insert_string(dict, "name", name))
			goto err;
		if (py_insert_bool(dict, "name", state))
			goto err;
		rt = py_append_obj(list, dict);
		Py_DECREF(dict); dict = NULL;
		if (rt) goto err;
	} else {
		if (qpol_policy_get_bool_iter(q, &iter))
			goto err;
		if (qpol_iterator_get_size(iter, &n_bools))
			goto err;
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&bool_datum))
				goto err;
			if (qpol_bool_get_name(q, bool_datum, &bool_name))
				goto err;
			if (qpol_bool_get_state(q, bool_datum, &state))
				goto err;

			dict = PyDict_New(); 
			if (!dict) goto err;
			if (py_insert_string(dict, "name", bool_name))
				goto err;
			if (py_insert_bool(dict, "state", state))
				goto err;
			rt = py_append_obj(list, dict);
			Py_DECREF(dict); dict = NULL;
			if (rt) goto err;
		}
		qpol_iterator_destroy(&iter);
	}
	goto cleanup;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(error));
	py_decref(list); list = NULL;
	py_decref(dict); dict = NULL;

cleanup:
	qpol_iterator_destroy(&iter);
	errno = error; 
	return list;
}
Esempio n. 10
0
/**
 * Gets statistics regarding a policy's attributes.
 * If this function is given a name, it will attempt to
 * get statistics about a particular attribute; otherwise
 * the function gets statistics about all of the policy's
 * attributes.
 *
 * @param name Reference to an attribute's name; if NULL,
 * all object classes will be considered
 * @param policydb Reference to a policy
 *
 * @return 0 on success, < 0 on error.
 */
static PyObject* get_attribs(const char *name, const apol_policy_t * policydb)
{
	PyObject *obj;
	apol_attr_query_t *attr_query = NULL;
	apol_vector_t *v = NULL;
	const qpol_type_t *type_datum = NULL;
	size_t n_attrs, i;
	int error = 0;
	int rt = 0;
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	/* we are only getting information about 1 attribute */
	if (name != NULL) {
		attr_query = apol_attr_query_create();
		if (!attr_query)
			goto err;
		if (apol_attr_query_set_attr(policydb, attr_query, name))
			goto err;
		if (apol_attr_get_by_query(policydb, attr_query, &v))
			goto err;
		apol_attr_query_destroy(&attr_query);
		if (apol_vector_get_size(v) == 0) {
			apol_vector_destroy(&v);
			errno = EINVAL;
			goto err;
		}

		type_datum = apol_vector_get_element(v, (size_t) 0);
		obj = get_attr(type_datum, policydb);
		rt = py_append_obj(list, obj);
		Py_DECREF(obj);
		if (rt) goto err;
	} else {
		attr_query = apol_attr_query_create();
		if (!attr_query)
			goto err;
		if (apol_attr_get_by_query(policydb, attr_query, &v))
			goto err;
		apol_attr_query_destroy(&attr_query);
		n_attrs = apol_vector_get_size(v);

		for (i = 0; i < n_attrs; i++) {
			/* get qpol_type_t* item from vector */
			type_datum = (qpol_type_t *) apol_vector_get_element(v, (size_t) i);
			if (!type_datum)
				goto err;
			obj = get_attr(type_datum, policydb);
			rt = py_append_obj(list, obj);
			Py_DECREF(obj);
			if (rt) goto err;
		}
	}
	apol_vector_destroy(&v);
	goto cleanup;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
	py_decref(list); list = NULL;

cleanup:
	apol_attr_query_destroy(&attr_query);
	apol_vector_destroy(&v);
	errno = error;
	return list;
}