/**
 *  @file
 *  Command line tool to search TE rules.
 *
 *  @author Frank Mayer  mayerf@tresys.com
 *  @author Jeremy A. Mowery jmowery@tresys.com
 *  @author Paul Rosenfeld  prosenfeld@tresys.com
 *  @author Thomas Liu  <tliu@redhat.com>
 *  @author Dan Walsh  <dwalsh@redhat.com>
 *
 *  Copyright (C) 2003-2008 Tresys Technology, LLC
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * This is a modified version of seinfo to be used as part of a library for
 * Python bindings.
 */

#include "common.h"
#include "policy.h"

/* libapol */
#include <apol/policy-query.h>
#include <apol/render.h>
#include <apol/util.h>
#include <apol/vector.h>

/* libqpol */
#include <qpol/policy.h>
#include <qpol/util.h>

/* other */
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define COPYRIGHT_INFO "Copyright (C) 2003-2007 Tresys Technology, LLC"

enum input
{
	TYPE, ATTRIBUTE, ROLE, USER, PORT, BOOLEAN, CLASS, SENS, CATS
};

static int py_insert_long(PyObject *dict, const char *name, int value)
{
	int rt;
	PyObject *obj = PyLong_FromLong(value);
	if (!obj) return -1;
	rt = PyDict_SetItemString(dict, name, obj);
	Py_DECREF(obj);
	return rt;
}

static int py_insert_bool(PyObject *dict, const char *name, int value)
{
	int rt;
	PyObject *obj = PyBool_FromLong(value);
	if (!obj) return -1;
	rt = PyDict_SetItemString(dict, name, obj);
	Py_DECREF(obj);
	return rt;
}

/**
 * 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;
}

/**
 * Compare two qpol_cat_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_type_datum_t object
 * @param datum2 Reference to a qpol_type_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_cat_datum_compare(const void *datum1, const void *datum2, void *data)
{
	const qpol_cat_t *cat_datum1 = NULL, *cat_datum2 = NULL;
	apol_policy_t *policydb = NULL;
	qpol_policy_t *q;
	uint32_t val1, val2;

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

	if (!datum1 || !datum2)
		goto exit_err;
	cat_datum1 = datum1;
	cat_datum2 = datum2;

	if (qpol_cat_get_value(q, cat_datum1, &val1))
		goto exit_err;
	if (qpol_cat_get_value(q, cat_datum2, &val2))
		goto exit_err;

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

      exit_err:
	assert(0);
	return 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;
}

/**
 * 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;
}

/**
 * Get the alias of a type.
 *
 * @param type_datum Reference to sepol type_datum
 * @param policydb Reference to a policy
 * attributes
 */
static PyObject* get_type_aliases(const qpol_type_t * type_datum, const apol_policy_t * policydb)
{
	qpol_iterator_t *iter = NULL;
	size_t alias_size;
	unsigned char isattr, isalias;
	const char *type_name = NULL;
	const char *alias_name;
	int error = 0;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	if (qpol_type_get_name(q, type_datum, &type_name))
		goto cleanup;
	if (qpol_type_get_isattr(q, type_datum, &isattr))
		goto cleanup;
	if (qpol_type_get_isalias(q, type_datum, &isalias))
		goto cleanup;

	if (qpol_type_get_alias_iter(q, type_datum, &iter))
		goto cleanup;
	if (qpol_iterator_get_size(iter, &alias_size))
		goto cleanup;
	if (alias_size >  0) {
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&alias_name))
				goto err;
			if (py_append_string(list, alias_name))
				goto err;
		}
	}
	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;
}

/**
 * Gets a textual representation of an attribute, and 
 * all of that attribute's types.
 *
 * @param type_datum Reference to sepol type_datum
 * @param policydb Reference to a policy
 */
static PyObject* get_attr(const qpol_type_t * type_datum, const apol_policy_t * policydb)
{
	PyObject *list = NULL;
	const qpol_type_t *attr_datum = NULL;
	qpol_iterator_t *iter = NULL;
	const char *attr_name = NULL, *type_name = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	unsigned char isattr;
	int error = 0;
	int rt = 0;
	PyObject *dict = PyDict_New(); 
	if (!dict) goto err;

	if (qpol_type_get_name(q, type_datum, &attr_name))
		goto err;

	if (py_insert_string(dict, "name", attr_name))
		goto err;

	/* get an iterator over all types this attribute has */
	if (qpol_type_get_isattr(q, type_datum, &isattr))
		goto err;

	if (isattr) {	       /* sanity check */
		if (qpol_type_get_type_iter(q, type_datum, &iter))
			goto err;
		list = PyList_New(0);
		if (!list) goto err;
		
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&attr_datum))
				goto err;
			if (qpol_type_get_name(q, attr_datum, &type_name))
				goto err;
			if (py_append_string(list, type_name))
				goto err;
		}
		qpol_iterator_destroy(&iter);
		rt = PyDict_SetItemString(dict, "types", list);
		Py_DECREF(list); list = NULL;
		if (rt) goto err;
	} else		       /* this should never happen */
		goto err;
	goto cleanup;

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

cleanup:
	qpol_iterator_destroy(&iter);
	errno =	error;
	return dict;
}

/**
 * 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;
}

/**
 * Get a textual representation of a type, and
 * all of that type's attributes.
 *
 * @param type_datum Reference to sepol type_datum
 * @param policydb Reference to a policy
 */
static PyObject* get_type_attrs(const qpol_type_t * type_datum, const apol_policy_t * policydb)
{
	qpol_iterator_t *iter = NULL;
	const char *attr_name = NULL;
	const qpol_type_t *attr_datum = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	int error = 0;
	PyObject *list = PyList_New(0);
	if (!list) goto err;

	if (qpol_type_get_attr_iter(q, type_datum, &iter))
		goto err;

	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		if (qpol_iterator_get_item(iter, (void **)&attr_datum))
			goto err;
		if (qpol_type_get_name(q, attr_datum, &attr_name))
			goto err;
		if (py_append_string(list, attr_name))
			goto err;
	}
	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;
}

static PyObject* get_type(const qpol_type_t * type_datum, const apol_policy_t * policydb) {

	PyObject *obj;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	const char *type_name = NULL;
	int error = 0;
	int rt;
	unsigned char isalias, ispermissive, isattr;
	PyObject *dict = PyDict_New(); 
	if (!dict) goto err;

	if (qpol_type_get_name(q, type_datum, &type_name))
		goto err;
	if (qpol_type_get_isalias(q, type_datum, &isalias))
		goto err;
	if (qpol_type_get_isattr(q, type_datum, &isattr))
		goto err;
	if (qpol_type_get_ispermissive(q, type_datum, &ispermissive))
		goto err;

	if (py_insert_string(dict, "name", type_name))
		goto err;

	if (py_insert_bool(dict, "permissive", ispermissive))
		goto err;

	if (!isattr && !isalias) {
		obj = get_type_attrs(type_datum, policydb);
		rt = py_insert_obj(dict, "attributes", obj);
		Py_DECREF(obj);
		if (rt) goto err;
	}

	obj = get_type_aliases(type_datum, policydb);
	rt = py_insert_obj(dict, "aliases", obj);
	Py_DECREF(obj);
	if (rt) goto err;
	goto cleanup;

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

cleanup:
	errno = error; 
	return dict;
}

/**
 * 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 name Reference to a boolean's name; if NULL,
 * all booleans will be considered
 * @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;
}

/**
 * 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;
}

/**
 * Prints a textual representation of an object class and possibly
 * all of that object class' permissions.
 *
 * @param type_datum Reference to sepol type_datum
 * @param policydb Reference to a policy
 */
static PyObject* get_class(const qpol_class_t * class_datum, const apol_policy_t * policydb)
{
	const char *class_name = NULL, *perm_name = NULL;
	qpol_iterator_t *iter = NULL;
	const qpol_common_t *common_datum = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	int error = 0;
	int rt;
	PyObject *list = NULL;
	PyObject *dict = PyDict_New();
	if (!dict) goto err;

	if (!class_datum)
		goto err;

	if (qpol_class_get_name(q, class_datum, &class_name))
		goto err;

	if (py_insert_string(dict, "name", class_name))
		goto err;
	/* get commons for this class */
	if (qpol_class_get_common(q, class_datum, &common_datum))
		goto err;

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

	if (common_datum) {
		if (qpol_common_get_perm_iter(q, common_datum, &iter))
			goto err;
		/* print perms for the common */
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&perm_name))
				goto err;
			if (py_append_string(list, perm_name))
				goto err;
		}
	}
	/* print unique perms for this class */
	if (qpol_class_get_perm_iter(q, class_datum, &iter))
		goto err;
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		if (qpol_iterator_get_item(iter, (void **)&perm_name))
			goto err;
		if (py_append_string(list, perm_name))
			goto err;
	}
	rt = py_insert_obj(dict, "permlist", list);
	Py_DECREF(list); list = NULL;
	if (rt) goto err;
	qpol_iterator_destroy(&iter);
	goto cleanup;

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

cleanup:
	errno = error;
	qpol_iterator_destroy(&iter);
	return dict;
}

/**
 * Get statistics regarding a policy's object classes.
 * If this function is given a name, it will attempt to
 * print statistics about a particular object class; otherwise
 * the function prints statistics about all of the policy's object
 * classes.
 *
 * @param name Reference to an object class' 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_classes(const char *name, const apol_policy_t * policydb)
{
	qpol_iterator_t *iter = NULL;
	size_t n_classes = 0;
	const qpol_class_t *class_datum = 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_class_by_name(q, name, &class_datum))
			goto err;
		obj = get_class(class_datum, policydb);
		rt = py_append_obj(list, obj);
		Py_DECREF(obj);
		if (rt) goto err;
	} else {
		if (qpol_policy_get_class_iter(q, &iter))
			goto err;
		if (qpol_iterator_get_size(iter, &n_classes))
			goto err;

		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&class_datum))
				goto err;
			obj = get_class(class_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;
}

/**
 * Gets statistics regarding a policy's users.
 * If this function is given a name, it will attempt to
 * get statistics about a particular user; otherwise
 * the function gets statistics about all of the policy's
 * users.
 *
 * @param name Reference to a user's name; if NULL,
 * all users will be considered
 * @param policydb Reference to a policy
 *
 * @return 0 on success, < 0 on error.
 */
static PyObject*  get_users(const char *name, const apol_policy_t * policydb)
{
	qpol_iterator_t *iter = NULL;
	const qpol_user_t *user_datum = 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_user_by_name(q, name, &user_datum)) {
			errno = EINVAL;
			goto err;
		}
		obj = get_user(user_datum, policydb);
		rt = py_append_obj(list, obj);
		Py_DECREF(obj);
		if (rt) goto err;
	} else {
		if (qpol_policy_get_user_iter(q, &iter))
			goto err;

		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&user_datum))
				goto err;
			obj = get_user(user_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;
}

/**
 * get a textual representation of a role, and 
 * all of that role's types.
 *
 * @param type_datum Reference to sepol type_datum
 * @param policydb Reference to a policy
 * types
 */
static PyObject* get_role(const qpol_role_t * role_datum, const apol_policy_t * policydb)
{
	const char *role_name = NULL, *type_name = NULL;
	const qpol_role_t *dom_datum = NULL;
	const qpol_type_t *type_datum = NULL;
	qpol_iterator_t *iter = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(policydb);
	size_t n_dom = 0, n_types = 0;
	int error = 0;
	int rt;
	PyObject *list = NULL;
	PyObject *dict = PyDict_New();
	if (!dict) goto err;

	if (qpol_role_get_name(q, role_datum, &role_name))
		goto err;
	if (py_insert_string(dict, "name", role_name))
		goto err;

	if (qpol_role_get_dominate_iter(q, role_datum, &iter))
		goto err;
	if (qpol_iterator_get_size(iter, &n_dom))
		goto err;
	if ((int)n_dom > 0) {
		list = PyList_New(0);
		if (!list) goto err;
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&dom_datum))
				goto err;
			if (qpol_role_get_name(q, dom_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;
	}
	qpol_iterator_destroy(&iter);
	
	if (qpol_role_get_type_iter(q, role_datum, &iter))
		goto err;
	if (qpol_iterator_get_size(iter, &n_types))
		goto err;
	if ((int)n_types > 0) {
		list = PyList_New(0);
		if (!list) goto err;
		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&type_datum))
				goto err;
			if (qpol_type_get_name(q, type_datum, &type_name))
				goto err;
			if (py_append_string(list, type_name))
				goto err;
		}
		rt = py_insert_obj(dict, "types", 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:
	qpol_iterator_destroy(&iter);
	errno =	error;
	return dict;
}

/**
 * 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;
}

/**
 * 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;
}

/**
 * Get statistics regarding a policy's types.
 * If this function is given a name, it will attempt to
 * print statistics about a particular type; otherwise
 * the function prints statistics about all of the policy's types.
 *
 * @param name Reference to a type'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_types(const char *name, const apol_policy_t * policydb)
{
	const qpol_type_t *type_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 was provided, only print that name */
	if (name != NULL) {
		if (qpol_policy_get_type_by_name(q, name, &type_datum)) {
			errno = EINVAL;
			goto err;
		}
		obj = get_type(type_datum, policydb);
		rt = py_append_obj(list, obj);
		Py_DECREF(obj); 
		if (rt) goto err;
	} else {
		if (qpol_policy_get_type_iter(q, &iter))
			goto err;

		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
			if (qpol_iterator_get_item(iter, (void **)&type_datum))
				goto err;
			obj = get_type(type_datum, policydb);
			rt = py_append_obj(list, obj);
			Py_DECREF(obj); 
			if (rt) goto err;
		}
	}
	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;
}

PyObject* info( int type, const char *name)
{
	PyObject* output = NULL;

	switch(type) {
	/* display requested info */
	case TYPE:
		output = get_types(name, global_policy);
		break;
	case ATTRIBUTE:
		output = get_attribs(name, global_policy);
		break;
	case ROLE:
		output = get_roles(name, global_policy);
		break;
	case USER:
		output = get_users(name, global_policy);
		break;
	case CLASS:
		output = get_classes(name, global_policy);
		break;
	case BOOLEAN:
		output = get_booleans(name, global_policy);
		break;
	case PORT:
		output = get_ports(name, global_policy);
		break;
	case SENS:
		output = get_sens(name, global_policy);
		break;
	case CATS:
		output = get_cats(name, global_policy);
		break;
	default:
		errno = EINVAL;
		PyErr_SetString(PyExc_RuntimeError,strerror(errno));
		break;
	}

	return output;
}

PyObject *wrap_info(PyObject *UNUSED(self), PyObject *args){
    int type;
    const char *name;
    
    if (!global_policy) {
	    PyErr_SetString(PyExc_RuntimeError,"Policy not loaded");
	    return NULL;
    }

    if (!PyArg_ParseTuple(args, "iz", &type, &name))
        return NULL;

    return info(type, name);
}

void init_info (PyObject *m) {
    PyModule_AddIntConstant(m, "ATTRIBUTE", ATTRIBUTE);
    PyModule_AddIntConstant(m, "PORT", PORT);
    PyModule_AddIntConstant(m, "ROLE", ROLE);
    PyModule_AddIntConstant(m, "TYPE", TYPE);
    PyModule_AddIntConstant(m, "USER", USER);
    PyModule_AddIntConstant(m, "CLASS", CLASS);
    PyModule_AddIntConstant(m, "BOOLEAN", BOOLEAN);
    PyModule_AddIntConstant(m, "SENS", SENS);
    PyModule_AddIntConstant(m, "CATS", CATS);
}
