summaryrefslogtreecommitdiffstats
path: root/libapol/include/apol
diff options
context:
space:
mode:
Diffstat (limited to 'libapol/include/apol')
-rw-r--r--libapol/include/apol/Makefile.am35
-rw-r--r--libapol/include/apol/avrule-query.h373
-rw-r--r--libapol/include/apol/bool-query.h105
-rw-r--r--libapol/include/apol/bst.h178
-rw-r--r--libapol/include/apol/class-perm-query.h255
-rw-r--r--libapol/include/apol/condrule-query.h119
-rw-r--r--libapol/include/apol/constraint-query.h188
-rw-r--r--libapol/include/apol/context-query.h261
-rw-r--r--libapol/include/apol/domain-trans-analysis.h427
-rw-r--r--libapol/include/apol/fscon-query.h249
-rw-r--r--libapol/include/apol/infoflow-analysis.h387
-rw-r--r--libapol/include/apol/isid-query.h111
-rw-r--r--libapol/include/apol/mls-query.h228
-rw-r--r--libapol/include/apol/mls_level.h261
-rw-r--r--libapol/include/apol/mls_range.h270
-rw-r--r--libapol/include/apol/netcon-query.h364
-rw-r--r--libapol/include/apol/perm-map.h137
-rw-r--r--libapol/include/apol/permissive-query.h104
-rw-r--r--libapol/include/apol/polcap-query.h103
-rw-r--r--libapol/include/apol/policy-path.h194
-rw-r--r--libapol/include/apol/policy-query.h86
-rw-r--r--libapol/include/apol/policy.h166
-rw-r--r--libapol/include/apol/range_trans-query.h198
-rw-r--r--libapol/include/apol/rbacrule-query.h279
-rw-r--r--libapol/include/apol/relabel-analysis.h258
-rw-r--r--libapol/include/apol/render.h82
-rw-r--r--libapol/include/apol/role-query.h127
-rw-r--r--libapol/include/apol/terule-query.h321
-rw-r--r--libapol/include/apol/type-query.h172
-rw-r--r--libapol/include/apol/types-relation-analysis.h380
-rw-r--r--libapol/include/apol/user-query.h150
-rw-r--r--libapol/include/apol/util.h336
-rw-r--r--libapol/include/apol/vector.h335
33 files changed, 7239 insertions, 0 deletions
diff --git a/libapol/include/apol/Makefile.am b/libapol/include/apol/Makefile.am
new file mode 100644
index 0000000..0883c10
--- /dev/null
+++ b/libapol/include/apol/Makefile.am
@@ -0,0 +1,35 @@
+apoldir = $(includedir)/apol
+
+apol_HEADERS = \
+ avrule-query.h \
+ bool-query.h \
+ bst.h \
+ class-perm-query.h \
+ condrule-query.h \
+ constraint-query.h \
+ context-query.h \
+ domain-trans-analysis.h \
+ fscon-query.h \
+ infoflow-analysis.h \
+ isid-query.h \
+ mls-query.h \
+ mls_level.h \
+ mls_range.h \
+ netcon-query.h \
+ perm-map.h \
+ permissive-query.h \
+ polcap-query.h \
+ policy.h \
+ policy-path.h \
+ policy-query.h \
+ range_trans-query.h \
+ rbacrule-query.h \
+ relabel-analysis.h \
+ render.h \
+ role-query.h \
+ terule-query.h \
+ type-query.h \
+ types-relation-analysis.h \
+ user-query.h \
+ util.h \
+ vector.h
diff --git a/libapol/include/apol/avrule-query.h b/libapol/include/apol/avrule-query.h
new file mode 100644
index 0000000..1f4b072
--- /dev/null
+++ b/libapol/include/apol/avrule-query.h
@@ -0,0 +1,373 @@
+/**
+ * @file
+ *
+ * Routines to query access vector rules of a policy. These are
+ * allow, neverallow, auditallow, and dontaudit rules.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_AVRULE_QUERY_H
+#define APOL_AVRULE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_avrule_query apol_avrule_query_t;
+
+/**
+ * Execute a query against all access vector rules within the policy.
+ *
+ * @param p Policy within which to look up avrules.
+ * @param a Structure containing parameters for query. If this is
+ * NULL then return all avrules.
+ * @param v Reference to a vector of qpol_avrule_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_avrule_get_by_query(const apol_policy_t * p, const apol_avrule_query_t * a, apol_vector_t ** v);
+
+/**
+ * Execute a query against all syntactic access vector rules within
+ * the policy. If the policy has line numbers, then the returned list
+ *
+ * @param p Policy within which to look up avrules. The policy must
+ * be capable of having syntactic rules.
+ * @param a Structure containing parameters for query. If this is
+ * NULL then return all avrules.
+ * @param v Reference to a vector of qpol_syn_avrule_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_syn_avrule_get_by_query(const apol_policy_t * p, const apol_avrule_query_t * a, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new avrule query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all avrules within the policy. The caller must call
+ * apol_avrule_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized avrule query structure, or NULL upon error.
+ */
+ extern apol_avrule_query_t *apol_avrule_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced avrule query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param a Reference to a avrule query structure to destroy.
+ */
+ extern void apol_avrule_query_destroy(apol_avrule_query_t ** a);
+
+/**
+ * Set an avrule query to search only certain access vector rules
+ * within the policy. This is a bitmap; use the constants in
+ * libqpol/avrule_query.h (QPOL_RULE_ALLOW, etc.) to give the rule
+ * selections.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param rules Bitmap to indicate which rules to search, or 0 to
+ * search all rules.
+ *
+ * @return Always 0.
+ */
+ extern int apol_avrule_query_set_rules(const apol_policy_t * p, apol_avrule_query_t * a, unsigned int rules);
+
+/**
+ * Set an avrule query to return rules whose source symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * source, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_set_source(const apol_policy_t * p, apol_avrule_query_t * a, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set an avrule query to return rules whose source symbol is matched as a type
+ * or an attribute. The symbol will match both types and attributes by default.
+ * @see apol_avrule_query_set_source() to set the symbol to match.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE
+ * and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component
+ * to match.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_set_source_component(const apol_policy_t * p, apol_avrule_query_t * a, unsigned int component);
+
+/**
+ * Set an avrule query to return rules whose target symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * target, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_set_target(const apol_policy_t * p, apol_avrule_query_t * a, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set an avrule query to return rules whose target symbol is matched as a type
+ * or an attribute. The symbol will match both types and attributes by default.
+ * @see apol_avrule_query_set_target() to set the symbol to match.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE
+ * and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component
+ * to match.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_set_target_component(const apol_policy_t * p, apol_avrule_query_t * a, unsigned int component);
+
+/**
+ * Set an avrule query to return rules with this object (non-common)
+ * class. If more than one class are appended to the query, the
+ * rule's class must be one of those appended. (I.e., the rule's
+ * class must be a member of the query's classes.) Pass a NULL to
+ * clear all classes. Note that this performs straight string
+ * comparison, ignoring the regex flag.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param obj_class Name of object class to add to search set, or NULL
+ * to clear all classes.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_append_class(const apol_policy_t * p, apol_avrule_query_t * a, const char *obj_class);
+
+/**
+ * Set an avrule query to return rules with this permission. By
+ * default, if more than one permission are appended to the query, at
+ * least one of the rule's permissions must be one of those appended;
+ * that is, the intersection of query's and rule's permissions must be
+ * non-empty. (This behavior can be changed.) Pass a NULL to clear
+ * all permissions. Note that this performs a straight string
+ * comparison, ignoring the regex flag.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param perm Name of permission to add to search set, or NULL to
+ * clear all permissions.
+ *
+ * @return 0 on success, negative on error.
+ *
+ * @see apol_avrule_query_set_all_perms()
+ */
+ extern int apol_avrule_query_append_perm(const apol_policy_t * p, apol_avrule_query_t * a, const char *perm);
+
+/**
+ * Set an avrule query to return rules that are in conditionals and
+ * whose conditional uses a particular boolean variable.
+ * Unconditional rules will not be returned.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param bool_name Name of boolean that conditional must contain. If
+ * NULL then search all rules.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_avrule_query_set_bool(const apol_policy_t * p, apol_avrule_query_t * a, const char *bool_name);
+
+/**
+ * Set an avrule query to search only enabled rules within the policy.
+ * These include rules that are unconditional and those within enabled
+ * conditionals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param is_enabled Non-zero to search only enabled rules, 0 to
+ * search all rules.
+ *
+ * @return Always 0.
+ */
+ extern int apol_avrule_query_set_enabled(const apol_policy_t * p, apol_avrule_query_t * a, int is_enabled);
+
+/**
+ * Normally, if more than one permission are added to the query then
+ * all returned rules will have <em>at least one</em> of those
+ * permissions. If the all_perms flag is set, then returned rules
+ * will have <em>all</em> of the given permissions. This flag does
+ * nothing if no permissions are given.
+ *
+ * <em>Note:</em> If calling apol_syn_avrule_get_by_query(), the
+ * returned results may not be what is expected. For a given
+ * source-target-class triplet, all of the associated permissions are
+ * unioned together prior to executing the avrule query. Although a
+ * given syntactic AV rule might not have all of the matched
+ * permissions, the union of the rules' permissions will them. For
+ * example, consider these two allow rules:
+ *
+ *<pre>allow A B : C p1;
+ *allow A B : C p2;</pre>
+ *
+ * If the avrule query has both permissions p1 and p2 and the
+ * all_perms flag is set, then both of these syntactic rules will be
+ * returned by apol_syn_avrule_get_by_query().
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param all_perms Non-zero to match all permissions, zero to match
+ * any permission.
+ *
+ * @return Always 0.
+ *
+ * @see apol_avrule_query_append_perm()
+ */
+ extern int apol_avrule_query_set_all_perms(const apol_policy_t * p, apol_avrule_query_t * a, int all_perms);
+
+/**
+ * Set an avrule query to treat the source symbol as any. That is,
+ * use the same symbol for either source or target of a rule. This
+ * flag does nothing if the source symbol is not set.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param is_any Non-zero to use source symbol for any field, 0 to
+ * keep source as only source.
+ *
+ * @return Always 0.
+ */
+ extern int apol_avrule_query_set_source_any(const apol_policy_t * p, apol_avrule_query_t * a, int is_any);
+
+/**
+ * Set an avrule query to use regular expression searching for source
+ * and target types/attributes. Strings will be treated as regexes
+ * instead of literals. Matching will occur against the type name or
+ * any of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a AV rule query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_avrule_query_set_regex(const apol_policy_t * p, apol_avrule_query_t * a, int is_regex);
+
+/**
+ * Given a single avrule, return a newly allocated vector of
+ * qpol_syn_avrule_t pointers (relative to the given policy) which
+ * comprise that rule. The vector will be sorted by line numbers if
+ * the policy has line numbers. If the given perms vector is non-NULL
+ * and non-empty, then only return syntactic rules with at least one
+ * permission listed within the perms vector.
+ *
+ * @param p Policy from which to obtain syntactic rules.
+ * @param rule AV rule to convert.
+ * @param perms If non-NULL and non-empty, a list of permission
+ * strings. Returned syn avrules will have at least one permission in
+ * common with this list.
+ *
+ * @return A newly allocated vector of syn_avrule_t pointers. The
+ * caller is responsible for calling apol_vector_destroy() afterwards.
+ */
+ extern apol_vector_t *apol_avrule_to_syn_avrules(const apol_policy_t * p, const qpol_avrule_t * rule,
+ const apol_vector_t * perms);
+
+/**
+ * Given a vector of avrules (qpol_avrule_t pointers), return a newly
+ * allocated vector of qpol_syn_avrule_t pointers (relative to the
+ * given policy) which comprise all of those rules. The returned
+ * vector will be sorted by line numbers if the policy has line
+ * numbers. Also, it will not have any duplicate syntactic rules. If
+ * the given perms vector is non-NULL and non-empty, then only return
+ * syntactic rules with at least one permission listed within the
+ * perms vector.
+ *
+ * @param p Policy from which to obtain syntactic rules.
+ * @param rules Vector of AV rules to convert.
+ * @param perms If non-NULL and non-empty, a list of permission
+ * strings. Returned syn avrules will have at least one permission in
+ * common with this list.
+ *
+ * @return A newly allocated vector of syn_avrule_t pointers. The
+ * caller is responsible for calling apol_vector_destroy() afterwards.
+ */
+ extern apol_vector_t *apol_avrule_list_to_syn_avrules(const apol_policy_t * p, const apol_vector_t * rules,
+ const apol_vector_t * perms);
+
+/**
+ * Render an avrule to a string.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+ */
+ extern char *apol_avrule_render(const apol_policy_t * policy, const qpol_avrule_t * rule);
+
+/**
+ * Render a syntactic avrule to a string.
+ *
+ * @param policy Policy handler to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+*/
+ extern char *apol_syn_avrule_render(const apol_policy_t * policy, const qpol_syn_avrule_t * rule);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/bool-query.h b/libapol/include/apol/bool-query.h
new file mode 100644
index 0000000..a735eec
--- /dev/null
+++ b/libapol/include/apol/bool-query.h
@@ -0,0 +1,105 @@
+/**
+ * @file
+ * Public Interface for querying conditional booleans of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_BOOL_QUERY_H
+#define APOL_BOOL_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_bool_query apol_bool_query_t;
+
+/******************** booleans queries ********************/
+
+/**
+ * Execute a query against all booleans within the policy.
+ *
+ * @param p Policy within which to look up booleans.
+ * @param b Structure containing parameters for query. If this is
+ * NULL then return all booleans.
+ * @param v Reference to a vector of qpol_bool_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_bool_get_by_query(const apol_policy_t * p, apol_bool_query_t * b, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new boolean query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all booleans within the policy. The caller must call
+ * apol_bool_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized boolean query structure, or NULL upon error.
+ */
+ extern apol_bool_query_t *apol_bool_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced boolean query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param b Reference to a boolean query structure to destroy.
+ */
+ extern void apol_bool_query_destroy(apol_bool_query_t ** b);
+
+/**
+ * Set a boolean query to return only booleans that match this name.
+ * This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param b Boolean query to set.
+ * @param name Limit query to only booleans with this name, or NULL to
+ * unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_bool_query_set_bool(const apol_policy_t * p, apol_bool_query_t * b, const char *name);
+
+/**
+ * Set a boolean query to use regular expression searching for all of
+ * its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param b Boolean query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_bool_query_set_regex(const apol_policy_t * p, apol_bool_query_t * b, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_BOOL_QUERY_H */
diff --git a/libapol/include/apol/bst.h b/libapol/include/apol/bst.h
new file mode 100644
index 0000000..ca21a76
--- /dev/null
+++ b/libapol/include/apol/bst.h
@@ -0,0 +1,178 @@
+/**
+ * @file
+ * Contains the API for a binary search tree. The tree guarantees
+ * uniqueness of all entries within. Note that BST functions are not
+ * thread-safe. Use this if you need uniqueness in items; use
+ * vectors otherwise because they are faster.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_BST_H
+#define APOL_BST_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+ typedef struct apol_bst apol_bst_t;
+
+ typedef int (apol_bst_comp_func) (const void *a, const void *b, void *data);
+ typedef void (apol_bst_free_func) (void *elem);
+
+#include "vector.h"
+
+/**
+ * Allocate and initialize an empty binary search tree. The tree
+ * must have a comparison function, used when comparing nodes so as
+ * to determine how to sort them.
+ *
+ * @param cmp A comparison call back for the type of element stored
+ * in the BST. The expected return value from this function is less
+ * than, equal to, or greater than 0 if the first argument is less
+ * than, equal to, or greater than the second respectively. If this
+ * is NULL then do pointer address comparison.
+ * @param fr Function to call when destroying the tree. Each
+ * element of the tree will be passed into this function; it should
+ * free the memory used by that element. If this parameter is NULL,
+ * the elements will not be freed.
+ *
+ * @return A pointer to a newly created BST on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_bst_destroy() to free memory used.
+ */
+ extern apol_bst_t *apol_bst_create(apol_bst_comp_func * cmp, apol_bst_free_func * fr);
+
+/**
+ * Free a BST and any memory used by it. This will recursively
+ * invoke the free function that was stored within the tree when it
+ * was created.
+ *
+ * @param b Pointer to the BST to free. The pointer will be set to
+ * NULL afterwards. If already NULL then this function does nothing.
+ */
+ extern void apol_bst_destroy(apol_bst_t ** b);
+
+/**
+ * Allocate and return a vector that has been initialized with the
+ * contents of a binary search tree. If change_owner is zero then
+ * this function will make a <b>shallow copy of the BST's
+ * contents</b>; the BST will still <em>own</em> the objects.
+ * Otherwise the victor will gain ownership of the items; the BST can
+ * then be destroyed safely without affecting the vector. (The
+ * resulting vector will be sorted as per the BST's comparison
+ * function.)
+ *
+ * @param b Binary search tree from which to copy.
+ * @param change_owner If zero then do a shallow copy, else change
+ * item ownership.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used
+ * by the vector.
+ */
+ extern apol_vector_t *apol_bst_get_vector(apol_bst_t * b, int change_owner);
+
+/**
+ * Get the number of elements stored in the BST.
+ *
+ * @param b The BST from which to get the number of elements. Must
+ * be non-NULL.
+ *
+ * @return The number of elements in the BST; if b is NULL, return
+ * 0 and set errno.
+ */
+ extern size_t apol_bst_get_size(const apol_bst_t * v);
+
+/**
+ * Find an element within a BST and return it.
+ *
+ * @param b The BST from which to get the element.
+ * @param elem The element to find. (This will be the second
+ * parameter to the comparison function given in apol_bst_create().)
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater (the function given in apol_bst_create()).
+ * @param elem Location to write the found element. This value is
+ * undefined if the key did not match any elements.
+ *
+ * @return 0 if element was found, or < 0 if not found.
+ */
+ extern int apol_bst_get_element(const apol_bst_t * b, const void *elem, void *data, void **result);
+
+/**
+ * Insert an element to the BST. If the element already exists then
+ * do not insert it again.
+ *
+ * @param b The BST to which to add the element.
+ * @param elem The element to add.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater (the function given in apol_bst_create()).
+ *
+ * @return 0 if the item was inserted, 1 if the item already exists
+ * (and thus not inserted). On failure return < 0, set errno, and b
+ * will be unchanged.
+ */
+ extern int apol_bst_insert(apol_bst_t * b, void *elem, void *data);
+
+/**
+ * Insert an element into the BST, and then get the element back out.
+ * If the element did not already exist, then this function behaves
+ * the same as apol_bst_insert(). If however the element did exist,
+ * then the passed in element is freed (as per the BST's free
+ * function) and then the existing element is returned.
+ *
+ * @param b The BST to which to add the element.
+ * @param elem Reference to an element to add. If the element is
+ * new, then the pointer remains unchanged. Otherwise set the
+ * reference to the element already within the tree.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater (the function given in apol_bst_create()).
+ *
+ * @return 0 if the item was inserted, 1 if the item already exists
+ * (and thus not inserted). On failure return < 0, set errno, and b
+ * will be unchanged.
+ */
+ extern int apol_bst_insert_and_get(apol_bst_t * b, void **elem, void *data);
+
+/**
+ * Map a function across all the elements of the BST. Mapping occurs in
+ * the sorted order as defined by the original comparison function.
+ *
+ * @param node BST upon which to map against.
+ * @param fn Function pointer that takes 2 arguments, first is a
+ * pointer to the data in a node of the BST, second is an arbitrary
+ * data element. The function may change the BST node, but it must
+ * not affect the node's sorting order within the tree. This function
+ * should return >= 0 on success; a return of < 0 signals error and
+ * ends the mapping over the tree.
+
+ * @return Result of the last call to fn() (i.e., >= 0 on success < 0 on
+ * failure). If the tree is empty then return 0.
+ */
+ extern int apol_bst_inorder_map(const apol_bst_t * b, int (*fn) (void *, void *), void *data);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_BST_H */
diff --git a/libapol/include/apol/class-perm-query.h b/libapol/include/apol/class-perm-query.h
new file mode 100644
index 0000000..abb2fbb
--- /dev/null
+++ b/libapol/include/apol/class-perm-query.h
@@ -0,0 +1,255 @@
+/**
+ * @file
+ *
+ * Routines to query classes, commons, and permissions of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_CLASS_PERM_QUERY_H
+#define APOL_CLASS_PERM_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_class_query apol_class_query_t;
+ typedef struct apol_common_query apol_common_query_t;
+ typedef struct apol_perm_query apol_perm_query_t;
+
+/******************** object class queries ********************/
+
+/**
+ * Execute a query against all classes within the policy. The results
+ * will only contain object classes, not common classes.
+ *
+ * @param p Policy within which to look up classes.
+ * @param c Structure containing parameters for query. If this is
+ * NULL then return all object classes.
+ * @param v Reference to a vector of qpol_class_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_class_get_by_query(const apol_policy_t * p, apol_class_query_t * c, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new class query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all object classes within the policy. The caller must
+ * call apol_class_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized class query structure, or NULL upon error.
+ */
+ extern apol_class_query_t *apol_class_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced class query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param c Reference to a class query structure to destroy.
+ */
+ extern void apol_class_query_destroy(apol_class_query_t ** c);
+
+/**
+ * Set a class query to return only object classes that match this
+ * name. This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Class query to set.
+ * @param name Limit query to only classes with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_class_query_set_class(const apol_policy_t * p, apol_class_query_t * c, const char *name);
+
+/**
+ * Set a class query to return only object classes that inherit from a
+ * particular common class. Queries will not match classes without
+ * commons if this option is set. This function duplicates the
+ * incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Class query to set.
+ * @param name Limit query to only classes that inherit from this
+ * common class, or NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_class_query_set_common(const apol_policy_t * p, apol_class_query_t * c, const char *name);
+
+/**
+ * Set a class query to use regular expression searching for all of
+ * its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Class query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_class_query_set_regex(const apol_policy_t * p, apol_class_query_t * c, int is_regex);
+
+/******************** common class queries ********************/
+
+/**
+ * Execute a query against all common classes within the policy. The
+ * results will only contain common classes, not object classes.
+ *
+ * @param p Policy within which to look up common classes.
+ * @param c Structure containing parameters for query. If this is
+ * NULL then return all common classes.
+ * @param v Reference to a vector of qpol_common_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_common_get_by_query(const apol_policy_t * p, apol_common_query_t * c, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new common query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all common classes within the policy. The caller must
+ * call apol_common_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized common query structure, or NULL upon error.
+ */
+ extern apol_common_query_t *apol_common_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced common query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param c Reference to a common query structure to destroy.
+ */
+ extern void apol_common_query_destroy(apol_common_query_t ** c);
+
+/**
+ * Set a common query to return only common classes that match this
+ * name. This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Common query to set.
+ * @param name Limit query to only commons with this name, or NULL to
+ * unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_common_query_set_common(const apol_policy_t * p, apol_common_query_t * c, const char *name);
+
+/**
+ * Set a common query to use regular expression searching for all of
+ * its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Class query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_common_query_set_regex(const apol_policy_t * p, apol_common_query_t * c, int is_regex);
+
+/******************** permission queries ********************/
+
+/**
+ * Execute a query against all permissions (both those declared in
+ * classes as well as commons) within the policy. The results will
+ * contain char pointers to permission names. Thus if the same
+ * permission name is declared within multiple classes (e.g.,
+ * <tt>file/read</tt> and <tt>socket/read</tt>) then only one instance
+ * of <tt>read</tt> is returned.
+ *
+ * @param p Policy within which to look up permissions.
+ * @param pq Structure containing parameters for query. If this is
+ * NULL then return all permissions.
+ * @param v Reference to a vector of character pointers. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_perm_get_by_query(const apol_policy_t * p, apol_perm_query_t * pq, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new permission query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all permissions within the policy. The caller must call
+ * apol_perm_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized permission query structure, or NULL upon
+ * error.
+ */
+ extern apol_perm_query_t *apol_perm_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced permission
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param pq Reference to a permission query structure to destroy.
+ */
+ extern void apol_perm_query_destroy(apol_perm_query_t ** pq);
+
+/**
+ * Set a permission query to return only permissions that match this
+ * name. This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param pq Permission query to set.
+ * @param name Limit query to only permissions with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_perm_query_set_perm(const apol_policy_t * p, apol_perm_query_t * pq, const char *name);
+
+/**
+ * Set a permission query to use regular expression searching for all
+ * of its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param pq Permission query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_perm_query_set_regex(const apol_policy_t * p, apol_perm_query_t * pq, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/condrule-query.h b/libapol/include/apol/condrule-query.h
new file mode 100644
index 0000000..16bbb14
--- /dev/null
+++ b/libapol/include/apol/condrule-query.h
@@ -0,0 +1,119 @@
+/**
+ * @file
+ *
+ * Routines to query conditional expressions and conditional rules of
+ * a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_CONDRULE_QUERY_H
+#define APOL_CONDRULE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_cond_query apol_cond_query_t;
+
+/**
+ * Execute a query against all conditional expressions within the
+ * policy.
+ *
+ * @param p Policy within which to look up expressions.
+ * @param c Structure containing parameters for query. If this is
+ * NULL then return all expressions.
+ * @param v Reference to a vector of qpol_cond_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_cond_get_by_query(const apol_policy_t * p, apol_cond_query_t * c, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new cond query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all conditional expressions within the policy. The
+ * caller must call apol_cond_query_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized cond query structure, or NULL upon error.
+ */
+ extern apol_cond_query_t *apol_cond_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced cond query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param c Reference to a cond query structure to destroy.
+ */
+ extern void apol_cond_query_destroy(apol_cond_query_t ** c);
+
+/**
+ * Set a cond query to search only conditional expressions that use a
+ * certain boolean variable.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Cond rule query to set.
+ * @param name Limit query to expressions with this boolean, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_cond_query_set_bool(const apol_policy_t * p, apol_cond_query_t * c, const char *name);
+
+/**
+ * Set a cond query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Cond rule query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_cond_query_set_regex(const apol_policy_t * p, apol_cond_query_t * c, int is_regex);
+
+/**
+ * Given a conditional node, allocate and return a string
+ * representation of its conditional expression.
+ *
+ * @param p Policy handler, to report errors.
+ * @param cond Conditional node whose expression to render.
+ *
+ * @return A newly malloc()'d string representation of conditonal
+ * expression, or NULL on failure. The caller is responsible for
+ * calling free() on the returned string.
+ */
+ extern char *apol_cond_expr_render(const apol_policy_t * p, const qpol_cond_t * cond);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/constraint-query.h b/libapol/include/apol/constraint-query.h
new file mode 100644
index 0000000..9e5b077
--- /dev/null
+++ b/libapol/include/apol/constraint-query.h
@@ -0,0 +1,188 @@
+/**
+ * @file
+ *
+ * Routines to query constraint and validatetrans statements in a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_CONSTRAINT_QUERY_H
+#define APOL_CONSTRAINT_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+
+ typedef struct apol_constraint_query apol_constraint_query_t;
+ typedef struct apol_validatetrans_query apol_validatetrans_query_t;
+
+/******************** constraint queries ********************/
+
+/**
+ * Execute a query against all constraints within the policy.
+ *
+ * @param p Policy within which to look up constraints.
+ * @param c Structure containing parameters for query. If this is
+ * NULL then return all constraints.
+ * @param v Reference to a vector of qpol_constraint_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_constraint_get_by_query(const apol_policy_t * p, apol_constraint_query_t * c, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new constraint query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all constraints within the policy. The caller must call
+ * apol_constraint_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized constraint query structure, or NULL upon
+ * error.
+ */
+ extern apol_constraint_query_t *apol_constraint_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced constraint
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param c Reference to a constraint query structure to destroy.
+ */
+ extern void apol_constraint_query_destroy(apol_constraint_query_t ** c);
+
+/**
+ * Set a constraint query to return only constraints that use object
+ * classes that match this name. This function duplicates the
+ * incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Constraint query to set.
+ * @param name Limit query to only classes with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_constraint_query_set_class(const apol_policy_t * p, apol_constraint_query_t * c, const char *name);
+
+/**
+ * Set a constraint query to return only constraints that employ
+ * permissions that match this name. This function duplicates the
+ * incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Constraint query to set.
+ * @param name Limit query to only permissions with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_constraint_query_set_perm(const apol_policy_t * p, apol_constraint_query_t * c, const char *name);
+
+/**
+ * Set a constraint query to use regular expression searching for all
+ * of its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Constraint query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_constraint_query_set_regex(const apol_policy_t * p, apol_constraint_query_t * c, int is_regex);
+
+/******************** validatetrans queries ********************/
+
+/**
+ * Execute a query against all validatetrans statements within the
+ * policy.
+ *
+ * @param p Policy within which to look up validatetrans statements.
+ * @param vr Structure containing parameters for query. If this is
+ * NULL then return all validatetrans statements.
+ * @param v Reference to a vector of qpol_validatetrans_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_validatetrans_get_by_query(const apol_policy_t * p, apol_validatetrans_query_t * vt, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new validatetrans query structure. All
+ * fields are initialized, such that running this blank query results
+ * in returning all validatetrans within the policy. The caller must
+ * call apol_validatetrans_query_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized validatetrans query structure, or NULL upon
+ * error.
+ */
+ extern apol_validatetrans_query_t *apol_validatetrans_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced validatetrans
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param vt Reference to a validatetrans query structure to destroy.
+ */
+ extern void apol_validatetrans_query_destroy(apol_validatetrans_query_t ** vt);
+
+/**
+ * Set a validatetrans query to return only validatetrans that use
+ * object classes that match this name. This function duplicates the
+ * incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param vt Validatetrans query to set.
+ * @param name Limit query to only classes with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_validatetrans_query_set_class(const apol_policy_t * p, apol_validatetrans_query_t * vt, const char *name);
+
+/**
+ * Set a validatetrans query to use regular expression searching for
+ * all of its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param vt Validatetrans query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_validatetrans_query_set_regex(const apol_policy_t * p, apol_validatetrans_query_t * vt, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/context-query.h b/libapol/include/apol/context-query.h
new file mode 100644
index 0000000..2ee269c
--- /dev/null
+++ b/libapol/include/apol/context-query.h
@@ -0,0 +1,261 @@
+/**
+ * @file
+ * Public interface for querying and manipulating a context.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_CONTEXT_QUERY_H
+#define APOL_CONTEXT_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "mls-query.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_context apol_context_t;
+
+/**
+ * Allocate and return a new context structure. All fields are
+ * initialized to nothing. The caller must call
+ * apol_context_destroy() upon the return value afterwards.
+ *
+ * @return An initialized context structure, or NULL upon error.
+ */
+ extern apol_context_t *apol_context_create(void);
+
+/**
+ * Allocate and return a new context structure, initialized from an
+ * existing qpol_context_t. The caller must call
+ * apol_context_destroy() upon the return value afterwards.
+ *
+ * @param p Policy from which the qpol_context_t was obtained.
+ * @param context The libqpol context for which to create a new apol
+ * context. This context will not be altered by this call.
+ *
+ * @return An initialized context structure, or NULL upon error.
+ */
+ extern apol_context_t *apol_context_create_from_qpol_context(const apol_policy_t * p, const qpol_context_t * context);
+
+/**
+ * Take a literal context string that may be missing components (e.g.,
+ * <b>user_u::type_t:s0:c0.c127</b>), fill in a newly allocated
+ * apol_context_t, and return it. If there is a MLS range component
+ * to the context, it will <b>not</b> expanded. The caller must call
+ * apol_context_destroy() upon the return value afterwards.
+ *
+ * Because this function creates a context without the benefit of a
+ * policy, its range is incomplete. Call apol_context_convert() to
+ * complete it.
+ *
+ * @param context_string Pointer to a string representing a (possibly
+ * incomplete) context, or NULL upon error.
+ *
+ * @return An initialized context structure, or NULL upon error.
+ */
+ extern apol_context_t *apol_context_create_from_literal(const char *context_string);
+
+/**
+ * Deallocate all memory associated with a context structure and then
+ * set it to NULL. This function does nothing if the context is
+ * already NULL.
+ *
+ * @param context Reference to a context structure to destroy.
+ */
+ extern void apol_context_destroy(apol_context_t ** context);
+
+/**
+ * Set the user field of a context structure. This function
+ * duplicates the incoming string.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param context Context to modify.
+ * @param user New user field to set, or NULL to unset this field.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_context_set_user(const apol_policy_t * p, apol_context_t * context, const char *user);
+
+/**
+ * Set the role field of a context structure. This function
+ * duplicates the incoming string.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param context Context to modify.
+ * @param role New role field to set, or NULL to unset this field.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_context_set_role(const apol_policy_t * p, apol_context_t * context, const char *role);
+
+/**
+ * Set the type field of a context structure. This function
+ * duplicates the incoming string.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param context Context to modify.
+ * @param type New type field to set, or NULL to unset this field.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_context_set_type(const apol_policy_t * p, apol_context_t * context, const char *type);
+
+/**
+ * Set the range field of a context structure. This function takes
+ * ownership of the range, such that the caller must not modify nor
+ * destroy it afterwards.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param context Context to modify.
+ * @param range New range field to set, or NULL to unset this field.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_context_set_range(const apol_policy_t * p, apol_context_t * context, apol_mls_range_t * range);
+
+/**
+ * Get the user field of a context structure.
+ *
+ * @param context Context to query.
+ *
+ * @return Context's user, or NULL if not set or upon error. Do not
+ * modify this string.
+ */
+ extern const char *apol_context_get_user(const apol_context_t * context);
+
+/**
+ * Get the role field of a context structure.
+ *
+ * @param context Context to query.
+ *
+ * @return Context's role, or NULL if not set or upon error. Do not
+ * modify this string.
+ */
+ extern const char *apol_context_get_role(const apol_context_t * context);
+
+/**
+ * Get the type field of a context structure.
+ *
+ * @param context Context to query.
+ *
+ * @return Context's type, or NULL if not set or upon error. Do not
+ * modify this string.
+ */
+ extern const char *apol_context_get_type(const apol_context_t * context);
+
+/**
+ * Get the range field of a context structure.
+ *
+ * @param context Context to query.
+ *
+ * @return Context's range, or NULL if not set or upon error. Do not
+ * modify this structure.
+ */
+ extern const apol_mls_range_t *apol_context_get_range(const apol_context_t * context);
+
+/**
+ * Compare two contexts, determining if one matches the other. The
+ * search context may have empty elements that indicate not to compare
+ * that field. Types will be matched if the two or any of their
+ * aliases are the same. The last parameter gives how to match ranges
+ * (assuming that search has a range); it must be one of
+ * APOL_QUERY_SUB, APOL_QUERY_SUPER, APOL_QUERY_EXACT or
+ * APOL_QUERY_INTERSECT as per apol_mls_range_compare(). If a context
+ * is not valid according to the policy then this function returns -1.
+ * If search is NULL then comparison always succeeds.
+ *
+ * @param p Policy within which to look up policy and MLS information.
+ * @param target Target context to compare.
+ * @param search Source context to compare.
+ * @param range_compare_type Specifies how to compare the ranges.
+ *
+ * @return 1 If comparison succeeds, 0 if not; -1 on error.
+ */
+ extern int apol_context_compare(const apol_policy_t * p,
+ const apol_context_t * target, const apol_context_t * search,
+ unsigned int range_compare_type);
+
+/**
+ * Given a complete context (user, role, type, and range if policy is
+ * MLS), determine if it is legal according to the supplied policy.
+ * (Check that the user has that role, the role has that type, etc.)
+ * This function will convert from aliases to canonical forms as
+ * necessary.
+ *
+ * @param p Policy within which to look up context information.
+ * @param context Context to check.
+ *
+ * @return 1 If context is legal, 0 if not; -1 on error.
+ */
+ extern int apol_context_validate(const apol_policy_t * p, const apol_context_t * context);
+
+/**
+ * Given a partial context, determine if it is legal according to the
+ * supplied policy. For fields that are not specified, assume that
+ * they would be legal. For example, if a user is given but not a
+ * role, then return truth if the user is in the policy. If the
+ * context is NULL then this function returns 1. This function will
+ * convert from aliases to canonical forms as necessary.
+ *
+ * @param p Policy within which to look up context information.
+ * @param context Context to check.
+ *
+ * @return 1 If context is legal, 0 if not; -1 on error.
+ */
+ extern int apol_context_validate_partial(const apol_policy_t * p, const apol_context_t * context);
+
+/**
+ * Given a context, allocate and return a string that represents the
+ * context. This function does not check if the context is valid or
+ * not. An asterisk ("*") represents fields that have not been set.
+ * For example, if a context has the role object_r but has no user nor
+ * type set, it will be rendered as "<sample>*:object_r:*</sample>"
+ * (assuming the given policy is not MLS).
+ *
+ * @param p Policy within which to look up MLS range information. If
+ * NULL, then attempt to treat the range as incomplete.
+ * @param context Context to render.
+ *
+ * @return A newly allocated string on success, which the caller must
+ * free afterwards. Upon error return NULL.
+ */
+ extern char *apol_context_render(const apol_policy_t * p, const apol_context_t * context);
+
+/**
+ * Given a context, convert the range within it (as per
+ * apol_mls_range_convert()) to a complete range. If the context has
+ * no range or has no literal range then do nothing.
+ *
+ * @param p Policy containing category information.
+ * @param context Context to convert.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_context_convert(const apol_policy_t * p, apol_context_t * context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_CONTEXT_QUERY_H */
diff --git a/libapol/include/apol/domain-trans-analysis.h b/libapol/include/apol/domain-trans-analysis.h
new file mode 100644
index 0000000..2e05748
--- /dev/null
+++ b/libapol/include/apol/domain-trans-analysis.h
@@ -0,0 +1,427 @@
+/**
+ * @file
+ *
+ * Routines to perform a domain transition analysis.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2005-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_DOMAIN_TRANS_ANALYSIS_H
+#define APOL_DOMAIN_TRANS_ANALYSIS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_domain_trans_analysis apol_domain_trans_analysis_t;
+ typedef struct apol_domain_trans_result apol_domain_trans_result_t;
+
+#define APOL_DOMAIN_TRANS_DIRECTION_FORWARD 0x01
+#define APOL_DOMAIN_TRANS_DIRECTION_REVERSE 0x02
+
+#define APOL_DOMAIN_TRANS_SEARCH_VALID 0x01
+#define APOL_DOMAIN_TRANS_SEARCH_INVALID 0x02
+#define APOL_DOMAIN_TRANS_SEARCH_BOTH (APOL_DOMAIN_TRANS_SEARCH_VALID|APOL_DOMAIN_TRANS_SEARCH_INVALID)
+
+/******************* table operation functions ****************************/
+
+/**
+ * Build the table of domain transitions for a policy if not already built.
+ * @param policy The policy for which to build the table; if the table
+ * already exists for this policy, nothing is done.
+ * @return 0 on success and < 0 on failure; if the call fails,
+ * errno will be set and the table will be destroyed.
+ */
+ extern int apol_policy_build_domain_trans_table(apol_policy_t * policy);
+
+/**
+ * @deprecated Use apol_policy_build_domain_trans_table().
+ */
+ extern int apol_policy_domain_trans_table_build(apol_policy_t * policy) __attribute__ ((deprecated));
+
+/**
+ * Reset the state of the domain transition table in a policy. This
+ * is needed because by default subsequent calls to
+ * apol_domain_trans_analysis_do() will not produce results generated
+ * in a previous call. If calls are to be considered independent or
+ * calls in a different direction are desired, call this function
+ * prior to apol_domain_trans_analysis_do(). If the table was not
+ * built yet then this function does nothing.
+ *
+ * @param policy Policy containing the table for which the state
+ * should be reset.
+ */
+ extern void apol_policy_reset_domain_trans_table(apol_policy_t * policy);
+
+/**
+ * @deprecated Use apol_policy_reset_domain_trans_table().
+ */
+ extern void apol_domain_trans_table_reset(apol_policy_t * policy) __attribute__ ((deprecated));
+
+/*************** functions to do domain transition anslysis ***************/
+
+/**
+ * Allocate and return a new domain transition analysis structure. All
+ * fields are cleared; one must fill in the details of the analysis
+ * before running it. The caller must call apol_domain_trans_analysis_destroy()
+ * upon the return value afterwards.
+ * @return An initialized domain transition analysis structure, or NULL
+ * upon error; if an error occurs errno will be set.
+ */
+ extern apol_domain_trans_analysis_t *apol_domain_trans_analysis_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced domain transition
+ * analysis structure, and then set it to NULL. This function does nothing if
+ * the analysis is already NULL.
+ * @param dta Reference to a domain transition analysis structure to destroy.
+ */
+ extern void apol_domain_trans_analysis_destroy(apol_domain_trans_analysis_t ** dta);
+
+/**
+ * Set the direction of the transitions with respect to the start type.
+ * Must be either APOL_DOMAIN_TRANS_DIRECTION_FORWARD
+ * or APOL_DOMAIN_TRANS_DIRECTION_REVERSE.
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param direction The direction to analyze using one of the two values above.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_set_direction(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ unsigned char direction);
+
+/**
+ * Set the analysis to search for transitions based upon whether they
+ * would be permitted. The value must be one of APOL_DOMAIN_TRANS_SEARCH_*
+ * defined above. The default for a newly created analysis is to search
+ * for only valid transitions (i.e. APOL_DOMAIN_TRANS_SEARCH_VALID).
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param valid One of APOL_DOMAIN_TRANS_SEARCH_*.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_set_valid(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ unsigned char valid);
+
+/**
+ * Set the analysis to begin searching using a given type. This function
+ * must be called prior to running the analysis. If a previous type
+ * was set, it will be free()'d first.
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param type_name Name of the type from which to begin searching.
+ * Must be non-NULL. This string will be duplicated.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_set_start_type(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *type_name);
+
+/**
+ * Set the analysis to return only types matching a regular expression.
+ * Note that the regular expression will also match types' aliases.
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param result Only return results matching this regular expression, or
+ * NULL to return all types.
+ * @return 0 on success, and < 0 on failure; if the call fails,
+ * errno will be set.
+ */
+ extern int apol_domain_trans_analysis_set_result_regex(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *regex);
+
+/**
+ * Set the analysis to return only types having access (via allow
+ * rules) to this type. <b>This is only valid for forward
+ * analysis.</b> If more than one type is appended to the query, the
+ * resulting type must have access to at least one of the appended
+ * types. Pass a NULL to clear all previously appended types. <b>If
+ * access types are appended, the caller must also call
+ * apol_domain_trans_analysis_append_class() at least once with
+ * a valid class and apol_domain_trans_analysis_append_perm() at
+ * least once with a valid permission.</b>
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param type_name Type to which a result must have access.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_append_access_type(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *type_name);
+
+/**
+ * Set the analysis to return only types having access (via allow
+ * rules) to this class with the given permission. <b>This is only
+ * valid for forward analysis.</b> If more than one class is appended
+ * to the query, the resulting type must have access to at least one
+ * of the appended classes. If more than one permission is appended
+ * for the same class, the resulting type must have at least one of
+ * the appended permissions for that class. Pass a NULL to both
+ * strings to clear all previously appended classes and
+ * permissions. <b>If access classes and permissions are appended,
+ * the caller must also call
+ * apol_domain_trans_analysis_append_access_type() at least once with
+ * a valid type.</b>
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param class_name The class to which a result must have access.
+ * @param perm_name The permission which a result must have
+ * for the given class.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ * @deprecated This function has been split into
+ * apol_domain_trans_analysis_append_class() and
+ * apol_domain_trans_analysis_append_perm()
+ */
+ extern int apol_domain_trans_analysis_append_class_perm(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *class_name, const char *perm_name)
+ __attribute__ ((deprecated));
+
+/**
+ * Set the analysis to return only types having access (via allow
+ * rules) to this class. <b>This is only valid for forward
+ * analysis.</b> If more than one class is appended to the query, the
+ * resulting type must have access to at least one of the appended
+ * classes. Pass a NULL to clear all previously appended classes.
+ * <b>If access classes are appended, the caller must also call
+ * apol_domain_trans_analysis_append_access_type() at least once with
+ * a valid type and apol_domain_trans_analysis_append_perm() with a
+ * valid permission.</b>
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param class_name The class to which a result must have access.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_append_class(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *class_name);
+
+/**
+ * Set the analysis to return only types having access (via allow
+ * rules) to this permission. <b>This is only valid for forward
+ * analysis.</b> If more than one permission is appended the
+ * resulting type must have at least one of the appended permissions.
+ * Pass a NULL to clear all previously appended permissions. <b>If
+ * access permissions are appended, the caller must also call
+ * apol_domain_trans_analysis_append_access_type() at least once with
+ * a valid type and apol_domain_trans_analysis_append_class() at
+ * least once with a valid class.</b>
+ * @param policy Policy handler, to report errors.
+ * @param dta Domain transition analysis to set.
+ * @param perm_name The permission which a result must have.
+ * @return 0 on success, and < 0 on error; if the call fails,
+ * errno will be set and dta will be unchanged.
+ */
+ extern int apol_domain_trans_analysis_append_perm(const apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ const char *perm_name);
+
+/**
+ * Execute a domain transition analysis against a particular policy.
+ * @param policy Policy containing the table to use.
+ * @param dta A non-NULL structure containng parameters for analysis.
+ * @param results A reference pointer to a vector of
+ * apol_domain_trans_result_t. The vector will be allocated by this
+ * function. The caller must call apol_vector_destroy()
+ * afterwards. This will be set to NULL upon error.
+ * @return 0 on success and < 0 on failure; if the call fails,
+ * errno will be set and *results will be NULL.
+ *
+ * @see apol_policy_reset_domain_trans_table()
+ */
+ extern int apol_domain_trans_analysis_do(apol_policy_t * policy, apol_domain_trans_analysis_t * dta,
+ apol_vector_t ** results);
+
+/***************** functions for accessing results ************************/
+
+/**
+ * Return the start type of the transition in an
+ * apol_domain_trans_result node. The caller should not free the
+ * returned pointer. If the transition in the node is not valid
+ * there may be no start type in which case NULL is returned.
+ * @param dtr Domain transition result node.
+ * @return Pointer to the start type of the transition.
+ */
+ extern const qpol_type_t *apol_domain_trans_result_get_start_type(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the entrypoint type of the transition in an
+ * apol_domain_trans_result node. The caller should not free the
+ * returned pointer. If the transition in the node is not valid
+ * there may be no entrypoint in which case NULL is returned.
+ * @param dtr Domain transition result node.
+ * @return Pointer to the entrypoint type of the transition.
+ */
+ extern const qpol_type_t *apol_domain_trans_result_get_entrypoint_type(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the end type of the transition in an apol_domain_trans_result
+ * node. The caller should not free the returned pointer. If the transition
+ * in the node is not valid there may be no end type in which case NULL
+ * is returned.
+ * @param dtr Domain transition result node.
+ * @return Pointer to the start type of the transition.
+ */
+ extern const qpol_type_t *apol_domain_trans_result_get_end_type(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of process transition rules (qpol_avrule_t
+ * pointers) in an apol_domain_trans_result node. The caller should
+ * not free the returned pointer. If the transition is invalid then
+ * the returned vector will be empty.
+ * @param dtr Domain transition result node.
+ * @return Vector of qpol_avrule_t relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_proc_trans_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of file entrypoint rules (qpol_avrule_t
+ * pointers) in an apol_domain_trans_result node. The caller should
+ * not free the returned pointer. If the transition is invalid then
+ * the returned vector will be empty.
+ * @return Vector of qpol_avrule_t relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_entrypoint_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of file execute rules (qpol_avrule_t pointers)
+ * in an apol_domain_trans_result node. The caller should not free
+ * the returned pointer. If the transition is invalid then the
+ * returned vector will be empty.
+ * @return Vector of qpol_avrule_t relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_exec_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of process setexec rules (qpol_avrule_t
+ * pointers) in an apol_domain_trans_result node. The caller should
+ * not free the returned pointer. For all policies of version 15 or
+ * later a transition requires either a setexec rule or a
+ * type_transition rule to be valid. Valid transitions may have
+ * both; if there is no rule, this function returns an empty vector.
+ * @param dtr Domain transition result node.
+ * @return Vector of qpol_avrule_t relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_setexec_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of type_transition rules (qpol_terule_t
+ * pointers) in an apol_domain_trans_result node. The caller should
+ * not free the returned pointer. For all policies of version 15 or
+ * later a transition requires either a setexec rule or a
+ * type_transition rule to be valid. Valid transitions may have
+ * both; if there is no rule, this function returns an empty vector.
+ * @param dtr Domain transition result node.
+ * @return Vector of qpol_terule_t relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_type_trans_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Determine if the transition in an apol_domain_trans_result node is valid.
+ * @param dtr Domain transition result node.
+ * @return 0 if invalid and non-zero if valid. If dtr is NULL, returns 0.
+ */
+ extern int apol_domain_trans_result_is_trans_valid(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Return the vector of access rules which satisfied the access
+ * types, classes, and permissions specified in the query. This is a
+ * vector of qpol_avrule_t pointers. The caller <b>should not</b>
+ * call apol_vector_destroy() upon the returned vector. This vector
+ * is only populated if access criteria were specified in the
+ * analysis.
+ *
+ * @param dtr Domain transition result node.
+ * @return Pointer to a vector of rules relative to the policy originally
+ * used to generate the results.
+ */
+ extern const apol_vector_t *apol_domain_trans_result_get_access_rules(const apol_domain_trans_result_t * dtr);
+
+/**
+ * Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t
+ * object. The caller is responsible for calling
+ * apol_domain_trans_result_destroy() upon the returned value.
+ *
+ * @param result Pointer to a domain trans result structure to
+ * destroy.
+ *
+ * @return A clone of the passed in result node, or NULL upon error.
+ */
+ extern apol_domain_trans_result_t *apol_domain_trans_result_create_from_domain_trans_result(const apol_domain_trans_result_t
+ * in);
+
+/**
+ * Free all memory used by an apol_domain_trans_result_t object and
+ * set it to NULL. This does nothing if the pointer is already NULL.
+ * <b>This should only be called for results created by
+ * apol_domain_trans_result_create_from_domain_trans_result() and not
+ * those returned from within vectors.</b>
+ *
+ * @param res Reference pointer to a result to destroy.
+ */
+ extern void apol_domain_trans_result_destroy(apol_domain_trans_result_t ** res);
+
+/************************ utility functions *******************************/
+/* define the following for rule type */
+#define APOL_DOMAIN_TRANS_RULE_PROC_TRANS 0x01
+#define APOL_DOMAIN_TRANS_RULE_EXEC 0x02
+#define APOL_DOMAIN_TRANS_RULE_EXEC_NO_TRANS 0x04
+#define APOL_DOMAIN_TRANS_RULE_ENTRYPOINT 0x08
+#define APOL_DOMAIN_TRANS_RULE_TYPE_TRANS 0x10
+#define APOL_DOMAIN_TRANS_RULE_SETEXEC 0x20
+
+/**
+ * Verify that a transition using the given three types is valid in the given
+ * policy. If not valid, return a value indicating the missing rules. If any
+ * type is NULL, rules that would contain that type are considered missing. A
+ * valid transition requires a process transition, an entrypoint, and an
+ * execute rule. If the policy is version 15 or later it also requires either
+ * a setexec rule or a type_transition rule. The value
+ * APOL_DOMAIN_TRANS_RULE_EXEC_NO_TRANS is not returned by this function.
+ *
+ * @param policy The policy containing the domain transition table to
+ * consult. Must be non-NULL.
+ * @param start_dom The starting domain of the transition. May be NULL.
+ * @param ep_type The entrypoint of the transition. May be NULL.
+ * @param end_dom The ending domain of the transition. May be NULL.
+ *
+ * @return 0 if the transition is valid, < 0 on error, or a bit-wise
+ * or'ed set of APOL_DOMAIN_TRANS_RULE_* from above (always > 0)
+ * representing the rules missing from the transition.
+ */
+ extern int apol_domain_trans_table_verify_trans(apol_policy_t * policy, const qpol_type_t * start_dom,
+ const qpol_type_t * ep_type, const qpol_type_t * end_dom);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_DOMAIN_TRANS_ANALYSIS_H */
diff --git a/libapol/include/apol/fscon-query.h b/libapol/include/apol/fscon-query.h
new file mode 100644
index 0000000..18d0920
--- /dev/null
+++ b/libapol/include/apol/fscon-query.h
@@ -0,0 +1,249 @@
+/**
+ * @file
+ * Public Interface for querying genfscons and fs_uses of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_FSCON_QUERY_H
+#define APOL_FSCON_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include "context-query.h"
+#include <string.h>
+#include <qpol/policy.h>
+
+ typedef struct apol_genfscon_query apol_genfscon_query_t;
+ typedef struct apol_fs_use_query apol_fs_use_query_t;
+
+/******************** genfscon queries ********************/
+
+/**
+ * Execute a query against all genfscons within the policy. The
+ * returned genfscons will be unordered.
+ *
+ * @param p Policy within which to look up genfscons.
+ * @param g Structure containing parameters for query. If this is
+ * NULL then return all genfscons.
+ * @param v Reference to a vector of qpol_genfscon_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_genfscon_get_by_query(const apol_policy_t * p, const apol_genfscon_query_t * g, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new genfscon query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all genfscons within the policy. The caller must call
+ * apol_genfscon_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized genfscon query structure, or NULL upon
+ * error.
+ */
+ extern apol_genfscon_query_t *apol_genfscon_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced genfscon
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param g Reference to a genfscon query structure to destroy.
+ */
+ extern void apol_genfscon_query_destroy(apol_genfscon_query_t ** g);
+
+/**
+ * Set a genfscon query to return only genfscons that act upon this
+ * filesystem.
+ *
+ * @param p Policy handler, to report errors.
+ * @param g Genfscon query to set.
+ * @param fs Limit query to only genfscons with this filesystem, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_genfscon_query_set_filesystem(const apol_policy_t * p, apol_genfscon_query_t * g, const char *fs);
+
+/**
+ * Set a genfscon query to return only genfscons that act upon this
+ * relative path. If the path includes a trailing slash, the search
+ * will ingore that slash.
+ *
+ * @param p Policy handler, to report errors.
+ * @param g Genfscon query to set.
+ * @param path Limit query to only genfscons with this path, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_genfscon_query_set_path(const apol_policy_t * p, apol_genfscon_query_t * g, const char *path);
+
+/**
+ * Set a genfscon query to return only genfscons that act upon this
+ * object class.
+ *
+ * @param p Policy handler, to report errors.
+ * @param g Genfscon query to set.
+ * @param class Limit query to only genfscons with this object class,
+ * which must be one of QPOL_CLASS_BLK_FILE, QPOL_CLASS_CHR_FILE,
+ * etc., or negative to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_genfscon_query_set_objclass(const apol_policy_t * p, apol_genfscon_query_t * g, int objclass);
+
+/**
+ * Set a genfscon query to return only genfscons matching a context.
+ * This function takes ownership of the context, such that the caller
+ * must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param g Genfscon query to set.
+ * @param context Limit query to only genfscons matching this context,
+ * or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_genfscon_query_set_context(const apol_policy_t * p,
+ apol_genfscon_query_t * g, apol_context_t * context, unsigned int range_match);
+
+/**
+ * Creates a string containing the textual representation of
+ * a genfscon type.
+ * @param p Reference to a policy.
+ * @param genfscon Reference to the genfscon statement to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_genfscon_render(const apol_policy_t * p, const qpol_genfscon_t * genfscon);
+
+/******************** fs_use queries ********************/
+
+/**
+ * Execute a query against all fs_uses within the policy. The
+ * returned fs_use statements will be unordered.
+ *
+ * @param p Policy within which to look up fs_use statements.
+ * @param f Structure containing parameters for query. If this is
+ * NULL then return all fs_use statements.
+ * @param v Reference to a vector of qpol_fs_use_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_fs_use_get_by_query(const apol_policy_t * p, const apol_fs_use_query_t * f, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new fs_use query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all fs_use statements within the policy. The caller must
+ * call apol_fs_use_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized fs_use query structure, or NULL upon error.
+ */
+ extern apol_fs_use_query_t *apol_fs_use_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced fs_use query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param f Reference to a fs_use query structure to destroy.
+ */
+ extern void apol_fs_use_query_destroy(apol_fs_use_query_t ** f);
+
+/**
+ * Set a fs_use query to return only fs_use statements that act upon
+ * this filesystem.
+ *
+ * @param p Policy handler, to report errors.
+ * @param f fs_use query to set.
+ * @param fs Limit query to only fs_use statements with this
+ * filesystem, or NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_fs_use_query_set_filesystem(const apol_policy_t * p, apol_fs_use_query_t * f, const char *fs);
+
+/**
+ * Set a fs_use query to return only fs_use statements with this
+ * behavior.
+ *
+ * @param p Policy handler, to report errors.
+ * @param f fs_use query to set.
+ * @param behavior Limit query to only fs_use statements with this
+ * object class, which must be one of QPOL_FS_USE_XATTR,
+ * QPOL_FS_USE_TRANS, etc., or negative to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_fs_use_query_set_behavior(const apol_policy_t * p, apol_fs_use_query_t * f, int behavior);
+
+/**
+ * Set a fs_use query to return only fs_use statements matching a
+ * context. This function takes ownership of the context, such that
+ * the caller must not modify nor destroy it afterwards. Note that if
+ * a context is set, then the resulting query will never return
+ * fs_use_psid statements.
+ *
+ * @param p Policy handler, to report errors.
+ * @param f fs_use query to set.
+ * @param context Limit query to only fs_use statements matching this
+ * context, or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_fs_use_query_set_context(const apol_policy_t * p,
+ apol_fs_use_query_t * f, apol_context_t * context, unsigned int range_match);
+
+/**
+ * Creates a string containing the textual representation of
+ * a fs_use type.
+ * @param p Reference to a policy.
+ * @param fsuse Reference to the fs_use statement to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_fs_use_render(const apol_policy_t * p, const qpol_fs_use_t * fsuse);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_FSCON_QUERY_H */
diff --git a/libapol/include/apol/infoflow-analysis.h b/libapol/include/apol/infoflow-analysis.h
new file mode 100644
index 0000000..61b00a9
--- /dev/null
+++ b/libapol/include/apol/infoflow-analysis.h
@@ -0,0 +1,387 @@
+/**
+ * @file
+ *
+ * Routines to perform an information flow analysis, both direct and
+ * transitive flows.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2003-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_INFOFLOW_ANALYSIS_H
+#define APOL_INFOFLOW_ANALYSIS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+/*
+ * Information flows can be either direct (A -> B) or transitive (A ->
+ * {stuff} -> B).
+ */
+#define APOL_INFOFLOW_MODE_DIRECT 0x01
+#define APOL_INFOFLOW_MODE_TRANS 0x02
+
+/*
+ * All operations are mapped in either an information flow in or an
+ * information flow out (using the permission map). These defines are
+ * for the two flow directions plus flows in both or either direction
+ * for queries and query results.
+ */
+#define APOL_INFOFLOW_IN 0x01
+#define APOL_INFOFLOW_OUT 0x02
+#define APOL_INFOFLOW_BOTH (APOL_INFOFLOW_IN|APOL_INFOFLOW_OUT)
+#define APOL_INFOFLOW_EITHER 0x04
+
+ typedef struct apol_infoflow_graph apol_infoflow_graph_t;
+ typedef struct apol_infoflow_analysis apol_infoflow_analysis_t;
+ typedef struct apol_infoflow_result apol_infoflow_result_t;
+ typedef struct apol_infoflow_step apol_infoflow_step_t;
+
+/**
+ * Deallocate all space associated with a particular information flow
+ * graph, including the pointer itself. Afterwards set the pointer to
+ * NULL.
+ *
+ * @param g Reference to an apol_infoflow_graph_t to destroy.
+ */
+ extern void apol_infoflow_graph_destroy(apol_infoflow_graph_t ** g);
+
+/********** functions to do information flow analysis **********/
+
+/**
+ * Execute an information flow analysis against a particular policy.
+ * The policy must have had a permission map loaded via
+ * apol_policy_open_permmap(), else this analysis will abort
+ * immediately.
+ *
+ * @param p Policy within which to look up allow rules.
+ * @param ia A non-NULL structure containing parameters for analysis.
+ * @param v Reference to a vector of apol_infoflow_result_t. The
+ * vector will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon
+ * error.
+ * @param g Reference to the information flow graph constructed for
+ * the given infoflow analysis object. The graph will be allocated by
+ * this function; the caller is responsible for calling
+ * apol_infoflow_graph_destroy() afterwards. This will be set to NULL
+ * upon error.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_do(const apol_policy_t * p,
+ const apol_infoflow_analysis_t * ia, apol_vector_t ** v, apol_infoflow_graph_t ** g);
+
+/**
+ * Execute an information flow analysis against a particular policy
+ * and a pre-built information flow graph. The analysis will keep the
+ * same criteria that were used to build the graph, sans differing
+ * starting type.
+ *
+ * @param p Policy within which to look up allow rules.
+ * @param g Existing information flow graph to analyze.
+ * @param type New string from which to begin analysis.
+ * @param v Reference to a vector of apol_infoflow_result_t. The
+ * vector will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_do_more(const apol_policy_t * p, apol_infoflow_graph_t * g, const char *type,
+ apol_vector_t ** v);
+
+/**
+ * Prepare an existing transitive infoflow graph to do further
+ * searches upon two specific start and end types. The analysis is by
+ * way of a BFS with random restarts; thus each call to
+ * apol_infoflow_analysis_trans_further_next() may possibly return
+ * additional paths. This function is needed to prepare the pool of
+ * initial states for the search.
+ *
+ * @param p Policy from which infoflow rules derived.
+ * @param g Existing transitive infoflow graph. If it was already
+ * prepared then those values will be first destroyed.
+ * @param start_type String from which to begin further analysis.
+ * @param end_type String for target infoflow paths.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_infoflow_analysis_trans_further_prepare(const apol_policy_t * p,
+ apol_infoflow_graph_t * g, const char *start_type,
+ const char *end_type);
+
+/**
+ * Find further transitive infoflow paths by way of a random restart.
+ * The infoflow graph must be first prepared by first calling
+ * apol_infoflow_analysis_trans_further_prepare(). This function will
+ * append to vector v any new results it finds.
+ *
+ * @param p Policy from which infoflow rules derived.
+ * @param g Prepared transitive infoflow graph.
+ * @param v Pointer to a vector of existing apol_infoflow_result_t
+ * pointers. If this functions finds additional unique results it
+ * will append them to this vector. If the pointer is NULL then this
+ * will allocate and return a new vector. It is the caller's
+ * responsibility to call apol_vector_destroy() afterwards.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_infoflow_analysis_trans_further_next(const apol_policy_t * p, apol_infoflow_graph_t * g,
+ apol_vector_t ** v);
+
+/********** functions to create/modify an analysis object **********/
+
+/**
+ * Allocate and return a new information analysis structure. All
+ * fields are cleared; one must fill in the details of the analysis
+ * before running it. The caller must call
+ * apol_infoflow_analysis_destroy() upon the return value afterwards.
+ *
+ * @return An initialized information flow analysis structure, or NULL
+ * upon error.
+ */
+ extern apol_infoflow_analysis_t *apol_infoflow_analysis_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced information
+ * flow analysis, and then set it to NULL. This function does nothing
+ * if the analysis is already NULL.
+ *
+ * @param ia Reference to an infoflow analysis structure to destroy.
+ */
+ extern void apol_infoflow_analysis_destroy(apol_infoflow_analysis_t ** ia);
+
+/**
+ * Set an information flow analysis mode to be either direct or
+ * transitive. This must be one of the values
+ * APOL_INFOFLOW_MODE_DIRECT, or APOL_INFOFLOW_MODE_TRANS. This
+ * function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param ia Infoflow analysis to set.
+ * @param mode Analysis mode, either direct or transitive.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_set_mode(const apol_policy_t * p, apol_infoflow_analysis_t * ia, unsigned int mode);
+
+/**
+ * Set an information flow analysis to search in a specific direction.
+ * For direct infoflow analysis this must be one of the values
+ * APOL_INFOFLOW_IN, APOL_INFOFLOW_OUT, APOL_INFOFLOW_BOTH, or
+ * APOL_INFOFLOW_EITHER; transitive infoflow only permits the first
+ * two. This function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param ia Infoflow analysis to set.
+ * @param dir Direction to analyze, using one of the defines above.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_set_dir(const apol_policy_t * p, apol_infoflow_analysis_t * ia, unsigned int dir);
+
+/**
+ * Set an information flow analysis to begin searching using a given
+ * type. This function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param ia Infoflow anlysis to set.
+ * @param name Begin searching types with this non-NULL name.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_set_type(const apol_policy_t * p, apol_infoflow_analysis_t * ia, const char *name);
+
+/**
+ * Set an information flow analysis to return paths that only go
+ * through this intermediate type. If more than one type is appended
+ * to the analysis, every step of a return path will go through at
+ * least one of the types. These intermediate types are ignored when
+ * running a direct information flow analysis.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param ia Infoflow analysis to set.
+ * @param type Intermediate type which a result must flow through. If
+ * NULL, then clear all existing intermediate types. (All paths will
+ * be returned.)
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_append_intermediate(const apol_policy_t * p, apol_infoflow_analysis_t * ia,
+ const char *type);
+
+/**
+ * Set an information flow analysis to return only rules with this
+ * object (non-common) class and permission. If more than one
+ * class/perm pair is appended to the query, every rule's class and
+ * permissions must be one of those appended. (I.e., the rule will be
+ * a member of the analysis's class/perm pairs.)
+ *
+ * @param policy Policy handler, to report errors.
+ * @param ia Infoflow analysis to set.
+ * @param class_name The class to which a result must have access. If
+ * NULL, then accept all class/perm pairs.
+ * @param perm_name The permission which a result must have for the
+ * given class. This may be NULL if class_name is also NULL.
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_append_class_perm(const apol_policy_t * p,
+ apol_infoflow_analysis_t * ia, const char *class_name,
+ const char *perm_name);
+
+/**
+ * Set an information flow analysis to return only rules with at least
+ * one permission whose weight is greater than or equal to the given
+ * minimum. Permission weights are retrieved from the currently
+ * loaded permission map. If the given minimum exceeds
+ * APOL_PERMMAP_MAX_WEIGHT it will be clamped to that value.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param ia Infoflow analysis to set.
+ * @param min_weight Minimum weight for rules, or negative to accept
+ * all rules.
+ * @return Always 0.
+ */
+ extern int apol_infoflow_analysis_set_min_weight(const apol_policy_t * p, apol_infoflow_analysis_t * ia, int min_weight);
+
+/**
+ * Set an information flow analysis to return only types matching a
+ * regular expression. Note that the regexp will also match types'
+ * aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param ia Information flow anlysis to set.
+ * @param result Only return types matching this regular expression, or
+ * NULL to return all types
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_infoflow_analysis_set_result_regex(const apol_policy_t * p, apol_infoflow_analysis_t * ia,
+ const char *result);
+
+/*************** functions to access infoflow results ***************/
+
+/**
+ * Return the direction of an information flow result. This will be
+ * one of APOL_INFOFLOW_IN, APOL_INFOFLOW_OUT, or APOL_INFOFLOW_BOTH.
+ *
+ * @param result Infoflow result from which to get direction.
+ * @return Direction of result or zero on error.
+ */
+ extern unsigned int apol_infoflow_result_get_dir(const apol_infoflow_result_t * result);
+
+/**
+ * Return the start type of an information flow result. The caller
+ * should not free the returned pointer.
+ *
+ * @param result Infoflow result from which to get start type.
+ * @return Pointer to the start type of the infoflow or NULL on error.
+ */
+ extern const qpol_type_t *apol_infoflow_result_get_start_type(const apol_infoflow_result_t * result);
+
+/**
+ * Return the end type of an information flow result. The caller
+ * should not free the returned pointer.
+ *
+ * @param result Infoflow result from which to get end type.
+ * @return Pointer to the end type of the infoflow or NULL on error.
+ */
+ extern const qpol_type_t *apol_infoflow_result_get_end_type(const apol_infoflow_result_t * result);
+
+/**
+ * Return the length of an information flow result. This represents
+ * how easily information flows from the start to end type, where
+ * lower numbers are easier than higher numbers. This is dependent
+ * upon the weights assigned in the currently loaded permission map.
+ *
+ * @param result Infoflow result from which to get length.
+ * @return Length of result or zero on error.
+ */
+ extern unsigned int apol_infoflow_result_get_length(const apol_infoflow_result_t * result);
+
+/**
+ * Return the vector of infoflow steps for a particular information
+ * flow result. This is a vector of apol_infoflow_step_t pointers.
+ * The caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. Note that for a direct infoflow analysis this
+ * vector will consist of exactly one step; for transitive analysis
+ * the vector will have multiple steps.
+ *
+ * @param result Infoflow result from which to get steps.
+ *
+ * @return Pointer to a vector of steps found between the result's
+ * start and end types or NULL on error.
+ */
+ extern const apol_vector_t *apol_infoflow_result_get_steps(const apol_infoflow_result_t * result);
+
+/**
+ * Return the starting type for an information flow step. The caller
+ * should not free the returned pointer.
+ *
+ * @param step Infoflow step from which to get start type.
+ * @return Pointer to the start type for this infoflow step or NULL on error.
+ */
+ extern const qpol_type_t *apol_infoflow_step_get_start_type(const apol_infoflow_step_t * step);
+
+/**
+ * Return the ending type for an information flow step. The caller
+ * should not free the returned pointer.
+ *
+ * @param step Infoflow step from which to get end type.
+ * @return Pointer to the start type for this infoflow step or NULL on error.
+ */
+ extern const qpol_type_t *apol_infoflow_step_get_end_type(const apol_infoflow_step_t * step);
+
+/**
+ * Return the weight of an information flow step. For a direct
+ * infoflow analysis the weight is zero. For a transitive
+ * analysis this is an integer value that quantatizes the amount of
+ * information that could flow between the start and end types; it is
+ * based upon the currently opened permission map. It will be a value
+ * between APOL_PERMMAP_MIN_WEIGHT and APOL_PERMMAP_MAX_WEIGHT,
+ * inclusive.
+ *
+ * @param step Infoflow step from which to get weight.
+ * @return Weight of step or < 0 on error.
+ */
+ extern int apol_infoflow_step_get_weight(const apol_infoflow_step_t * step);
+
+/**
+ * Return the vector of access rules for a particular information
+ * step. This is a vector of qpol_avrule_t pointers. The caller
+ * <b>should not</b> call apol_vector_destroy() upon the returned
+ * vector.
+ *
+ * @param step Infoflow flow step from which to get rules.
+ *
+ * @return Pointer to a vector of rules relative to the policy originally
+ * used to generate the results or NULL on error.
+ */
+ extern const apol_vector_t *apol_infoflow_step_get_rules(const apol_infoflow_step_t * step);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/isid-query.h b/libapol/include/apol/isid-query.h
new file mode 100644
index 0000000..6c66ae9
--- /dev/null
+++ b/libapol/include/apol/isid-query.h
@@ -0,0 +1,111 @@
+/**
+ * @file
+ * Public Interface for querying initial SIDs of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_ISID_QUERY_H
+#define APOL_ISID_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include "context-query.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_isid_query apol_isid_query_t;
+
+/******************** isid queries ********************/
+
+/**
+ * Execute a query against all initial SIDs within the policy. The
+ * returned isids will be unordered.
+ *
+ * @param p Policy within which to look up initial SIDs.
+ * @param i Structure containing parameters for query. If this is
+ * NULL then return all isids.
+ * @param v Reference to a vector of qpol_isid_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_isid_get_by_query(const apol_policy_t * p, const apol_isid_query_t * i, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new isid query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all initial SIDs within the policy. The caller must call
+ * apol_isid_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized isid query structure, or NULL upon error.
+ */
+ extern apol_isid_query_t *apol_isid_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced isid query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param i Reference to an isid query structure to destroy.
+ */
+ extern void apol_isid_query_destroy(apol_isid_query_t ** i);
+
+/**
+ * Set an isid query to return only initial SIDs with this name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param i isid query to set.
+ * @param name Limit query to only initial SIDs with this name, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_isid_query_set_name(const apol_policy_t * p, apol_isid_query_t * i, const char *name);
+
+/**
+ * Set an isid query to return only initial SIDs matching a context.
+ * This function takes ownership of the context, such that the caller
+ * must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param i isid query to set.
+ * @param context Limit query to only initial SIDs matching this
+ * context, or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_isid_query_set_context(const apol_policy_t * p,
+ apol_isid_query_t * i, apol_context_t * context, unsigned int range_match);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_ISID_QUERY_H */
diff --git a/libapol/include/apol/mls-query.h b/libapol/include/apol/mls-query.h
new file mode 100644
index 0000000..22ee916
--- /dev/null
+++ b/libapol/include/apol/mls-query.h
@@ -0,0 +1,228 @@
+/**
+ * @file
+ * Public interface for querying MLS components, and for
+ * sensitivities and categories within a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_MLS_QUERY_H
+#define APOL_MLS_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "mls_level.h"
+#include "mls_range.h"
+#include "vector.h"
+
+ typedef struct apol_level_query apol_level_query_t;
+ typedef struct apol_cat_query apol_cat_query_t;
+
+/* MLS comparisons function will return one of the following on
+ success or -1 on error */
+#define APOL_MLS_EQ 0
+#define APOL_MLS_DOM 1
+#define APOL_MLS_DOMBY 2
+#define APOL_MLS_INCOMP 3
+
+/**
+ * Determine if two sensitivities are actually the same. Either level
+ * or both could be using a sensitivity's alias, thus straight string
+ * comparison is not sufficient.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param sens1 First sensitivity to compare.
+ * @param sens2 Second sensitivity to compare.
+ *
+ * @return 1 If comparison succeeds, 0 if not; -1 on error.
+ */
+ extern int apol_mls_sens_compare(const apol_policy_t * p, const char *sens1, const char *sens2);
+
+/**
+ * Determine if two categories are actually the same. Either category
+ * or both could be using a category's alias, thus straight string
+ * comparison is not sufficient.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param cat1 First category to compare.
+ * @param cat2 Second category to compare.
+ *
+ * @return 1 If comparison succeeds, 0 if not; -1 on error.
+ */
+ extern int apol_mls_cats_compare(const apol_policy_t * p, const char *cat1, const char *cat2);
+
+/******************** level queries ********************/
+
+/**
+ * Execute a query against all levels within the policy. The results
+ * will only contain levels, not sensitivity aliases. The returned
+ * levels will be unordered.
+ *
+ * @param p Policy within which to look up levels.
+ * @param l Structure containing parameters for query. If this is
+ * NULL then return all levels.
+ * @param v Reference to a vector of qpol_level_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon
+ * upon error. Note that the vector may be empty if the policy is
+ * not an MLS policy.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_level_get_by_query(const apol_policy_t * p, apol_level_query_t * l, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new level query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all levels within the policy. The caller must call
+ * apol_level_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized level query structure, or NULL upon error.
+ */
+ extern apol_level_query_t *apol_level_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced level query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param l Reference to a level query structure to destroy.
+ */
+ extern void apol_level_query_destroy(apol_level_query_t ** l);
+
+/**
+ * Set a level query to return only levels that match this name. The
+ * name may be either a sensitivity or one of its aliases. This
+ * function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param l Level query to set.
+ * @param name Limit query to only sensitivities or aliases with this
+ * name, or NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_level_query_set_sens(const apol_policy_t * p, apol_level_query_t * l, const char *name);
+
+/**
+ * Set a level query to return only levels contain a particular
+ * category. The name may be either a category or one of its aliases.
+ * This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param l Level query to set.
+ * @param name Limit query to levels containing this category or
+ * alias, or NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_level_query_set_cat(const apol_policy_t * p, apol_level_query_t * l, const char *name);
+
+/**
+ * Set a level query to use regular expression searching for all of
+ * its fields. Strings will be treated as regexes instead of
+ * literals. Matching will occur against the sensitivity name or any
+ * of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param l Level query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_level_query_set_regex(const apol_policy_t * p, apol_level_query_t * l, int is_regex);
+
+/******************** category queries ********************/
+
+/**
+ * Execute a query against all categories within the policy. The
+ * results will only contain categories, not aliases. The returned
+ * categories will be unordered.
+ *
+ * @param p Policy within which to look up categories.
+ * @param c Structure containing parameters for query. If this is
+ * NULL then return all categories.
+ * @param v Reference to a vector of qpol_cat_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon
+ * upon error. Note that the vector could be empty if the policy is
+ * not an MLS policy.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_cat_get_by_query(const apol_policy_t * p, apol_cat_query_t * c, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new category query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all categories within the policy. The caller must call
+ * apol_cat_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized category query structure, or NULL upon
+ * error.
+ */
+ extern apol_cat_query_t *apol_cat_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced category
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param c Reference to a category query structure to destroy.
+ */
+ extern void apol_cat_query_destroy(apol_cat_query_t ** c);
+
+/**
+ * Set a category query to return only categories that match this
+ * name. The name may be either a category or one of its aliases.
+ * This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Category query to set.
+ * @param name Limit query to only categories or aliases with this
+ * name, or NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_cat_query_set_cat(const apol_policy_t * p, apol_cat_query_t * c, const char *name);
+
+/**
+ * Set a category query to use regular expression searching for all of
+ * its fields. Strings will be treated as regexes instead of literals.
+ * Matching will occur against the category name or any of its
+ * aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param c Category query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_cat_query_set_regex(const apol_policy_t * p, apol_cat_query_t * c, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_MLS_QUERY_H */
diff --git a/libapol/include/apol/mls_level.h b/libapol/include/apol/mls_level.h
new file mode 100644
index 0000000..12e86b4
--- /dev/null
+++ b/libapol/include/apol/mls_level.h
@@ -0,0 +1,261 @@
+/**
+ * @file
+ * Public interface for representing and manipulating an
+ * apol_mls_level object.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_MLS_LEVEL_H
+#define APOL_MLS_LEVEL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_mls_level apol_mls_level_t;
+
+/**
+ * Allocate and return a new MLS level structure. All fields are
+ * initialized to nothing. The caller must call
+ * apol_mls_level_destroy() upon the return value afterwards.
+ *
+ * @return An initialized MLS level structure, or NULL upon error.
+ */
+ extern apol_mls_level_t *apol_mls_level_create(void);
+
+/**
+ * Allocate and return an MLS level structure, initialized by an
+ * existing apol_mls_level_t object. The caller must call
+ * apol_mls_level_destroy() upon the return value afterwards.
+ *
+ * @param level Level to copy. If NULL then the returned MLS level
+ * will be initialized to nothing.
+ *
+ * @return An initialized MLS level structure, or NULL upon error.
+ */
+ extern apol_mls_level_t *apol_mls_level_create_from_mls_level(const apol_mls_level_t * level);
+
+/**
+ * Take a MLS level string (e.g., <b>S0:C0.C127</b>) and parse it.
+ * Fill in a newly allocated apol_mls_level_t and return it. This
+ * function needs a policy to resolve dots within categories. If the
+ * string represents an illegal level then return NULL. The caller
+ * must call apol_mls_level_destroy() upon the returned value
+ * afterwards.
+ *
+ * @param p Policy within which to validate mls_level_string.
+ * @param mls_level_string Pointer to a string representing a valid
+ * MLS level.
+ *
+ * @return A filled in MLS level structure, or NULL upon error.
+ */
+ extern apol_mls_level_t *apol_mls_level_create_from_string(const apol_policy_t * p, const char *mls_level_string);
+
+/**
+ * Take a literal MLS level string (e.g., <b>S0:C0.C127</b>), fill in
+ * a newly allocated apol_mls_level_t and return it. The category
+ * portion of the level will <strong>not</strong> be expanded (i.e.,
+ * dots will not be resolved). The caller must call
+ * apol_mls_level_destroy() upon the returned value afterwards.
+ *
+ * Because this function creates a level without the benefit of a
+ * policy, its category list is "incomplete" and thus most operations
+ * will fail. All functions other than apol_mls_level_render(),
+ * apol_mls_level_convert(), and apol_mls_level_is_literal() will
+ * result in error. Call apol_mls_level_convert() to make a literal
+ * MLS level complete, so that it can be used in all functions.
+ *
+ * @param mls_level_string Pointer to a string representing a
+ * (possibly invalid) MLS level.
+ *
+ * @return A filled in MLS level structure, or NULL upon error.
+ */
+ extern apol_mls_level_t *apol_mls_level_create_from_literal(const char *mls_level_string);
+
+/**
+ * Create a new apol_mls_level_t and initialize it with a
+ * qpol_mls_level_t. The caller must call apol_mls_level_destroy()
+ * upon the returned value afterwards.
+ *
+ * @param p Policy from which the qpol_mls_level_t was obtained.
+ * @param qpol_level The libqpol level for which to create a new
+ * apol level. This level will not be altered by this call.
+ *
+ * @return A MLS level structure initialized to the value of
+ * qpol_level, or NULL upon error.
+ */
+ extern apol_mls_level_t *apol_mls_level_create_from_qpol_mls_level(const apol_policy_t * p,
+ const qpol_mls_level_t * qpol_level);
+
+/**
+ * Create a new apol_mls_level_t and initialize it with a
+ * qpol_level_t. The caller must call apol_mls_level_destroy()
+ * upon the returned value afterwards.
+ *
+ * @param p Policy from which the qpol_level_t was obtained.
+ * @param qpol_level The libqpol level for which to create a new
+ * apol level. This level will not be altered by this call.
+ *
+ * @return A MLS level structure initialized to the value of
+ * qpol_level, or NULL upon error.
+ */
+ apol_mls_level_t *apol_mls_level_create_from_qpol_level_datum(const apol_policy_t * p, const qpol_level_t * qpol_level);
+
+/**
+ * Deallocate all memory associated with a MLS level structure and
+ * then set it to NULL. This function does nothing if the level is
+ * already NULL.
+ *
+ * @param level Reference to a MLS level structure to destroy.
+ */
+ extern void apol_mls_level_destroy(apol_mls_level_t ** level);
+
+/**
+ * Set the sensitivity component of an MLS level structure. This
+ * function duplicates the incoming string.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param level MLS level to modify.
+ * @param sens New sensitivity component to set, or NULL to unset this
+ * field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_mls_level_set_sens(const apol_policy_t * p, apol_mls_level_t * level, const char *sens);
+
+/**
+ * Get the sensitivity component of an MLS level structure.
+ *
+ * @param level MLS level to query.
+ *
+ * @return The sensitivity, or NULL upon error if it has not yet been
+ * set. Do not modify the return value.
+ */
+ extern const char *apol_mls_level_get_sens(const apol_mls_level_t * level);
+
+/**
+ * Add a category component of an MLS level structure. This function
+ * duplicates the incoming string.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param level MLS level to modify.
+ * @param cats New category component to append.
+ *
+ * @return 0 on success or < 0 on failure.
+ */
+ extern int apol_mls_level_append_cats(const apol_policy_t * p, apol_mls_level_t * level, const char *cats);
+
+/**
+ * Get the category component of an MLS level structure. This will be
+ * a vector of strings, sorted alphabetically.
+ *
+ * @param level MLS level to query.
+ *
+ * @return Vector of categories, or NULL upon error. Be aware that
+ * the vector could be empty if no categories have been set. Do not
+ * modify the return value.
+ */
+ extern const apol_vector_t *apol_mls_level_get_cats(const apol_mls_level_t * level);
+
+/**
+ * Compare two levels and determine their relationship to each other.
+ * Both levels must have their respective sensitivity and categories
+ * set. Levels may contain aliases in place of primary names. If
+ * level2 is NULL then this always returns APOL_MLS_EQ.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param target Target MLS level to compare.
+ * @param search Source MLS level to compare.
+ *
+ * @return One of APOL_MLS_EQ, APOL_MLS_DOM, APOL_MLS_DOMBY, or
+ * APOL_MLS_INCOMP; < 0 on error.
+ *
+ * @see apol_mls_level_validate()
+ */
+ extern int apol_mls_level_compare(const apol_policy_t * p, const apol_mls_level_t * level1,
+ const apol_mls_level_t * level2);
+
+/**
+ * Given a level, determine if it is legal according to the supplied
+ * policy. This function will convert from aliases to canonical forms
+ * as necessary.
+ *
+ * @param h Error reporting handler.
+ * @param p Policy within which to look up MLS information.
+ * @param level Level to check.
+ *
+ * @return 1 If level is legal, 0 if not; < 0 on error.
+ *
+ * @see apol_mls_level_compare()
+ */
+ extern int apol_mls_level_validate(const apol_policy_t * p, const apol_mls_level_t * level);
+
+/**
+ * Creates a string containing the textual representation of
+ * a MLS level.
+ * @param p Policy from which the MLS level is a member. If NULL,
+ * then attempt to treat the level as an incomplete level (as per
+ * apol_mls_level_create_from_literal()).
+ * @param level MLS level to render.
+ *
+ * @return A newly allocated string, or NULL upon error. The caller
+ * is responsible for calling free() upon the return value.
+ */
+ extern char *apol_mls_level_render(const apol_policy_t * p, const apol_mls_level_t * level);
+
+/**
+ * Given a policy and a MLS level created by
+ * apol_mls_level_create_from_literal(), convert the level to have a
+ * valid ("complete") list of categories. This will take the literal
+ * string stored within the level and resolve its category lists, such
+ * as by expanding dots. The level will keep its literal string, so
+ * that it may be converted again if given a different policy.
+ *
+ * @param p Policy containing category information.
+ * @param level MLS level to convert.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_mls_level_convert(const apol_policy_t * p, apol_mls_level_t * level);
+
+/**
+ * Determine if a level is literal (i.e., created from
+ * apol_mls_level_create_from_literal()). Note that converting a
+ * literal level (apol_mls_level_convert()) completes the level, but
+ * it is still a literal level.
+ *
+ * @param level Level to query.
+ *
+ * @return > 0 value if the level is literal, 0 if not, < 0 if unknown
+ * or upon error.
+ */
+ extern int apol_mls_level_is_literal(const apol_mls_level_t * level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_MLS_LEVEL_H */
diff --git a/libapol/include/apol/mls_range.h b/libapol/include/apol/mls_range.h
new file mode 100644
index 0000000..49dade7
--- /dev/null
+++ b/libapol/include/apol/mls_range.h
@@ -0,0 +1,270 @@
+/**
+ * @file
+ * Public interface for representing and manipulating the
+ * apol_mls_range object.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_MLS_RANGE_H
+#define APOL_MLS_RANGE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mls_level.h"
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_mls_range apol_mls_range_t;
+
+/**
+ * Allocate and return a new MLS range structure. All fields are
+ * initialized to nothing. The caller must call
+ * apol_mls_range_destroy() upon the return value afterwards.
+ *
+ * @return An initialized MLS range structure, or NULL upon error.
+ */
+ extern apol_mls_range_t *apol_mls_range_create(void);
+
+/**
+ * Allocate and return a new MLS range structure, initialized by an
+ * existing apol_mls_range_t. The caller must call
+ * apol_mls_range_destroy() upon the return value afterwards.
+ *
+ * @param range Range to copy. If NULL then the returned MLS range
+ * will be initialized to nothing.
+ *
+ * @return An initialized MLS range structure, or NULL upon error.
+ */
+ extern apol_mls_range_t *apol_mls_range_create_from_mls_range(const apol_mls_range_t * range);
+
+/**
+ * Take a MLS range string (e.g., <b>S0:C0.C10-S1:C0.C127</b>) and
+ * parse it. Fill in a newly allocated apol_mls_range_t and return
+ * it. This function needs a policy to resolve dots within categories
+ * and to ensure that the high level dominates the low. If the string
+ * represents an illegal range then return NULL. The caller must call
+ * apol_mls_range_destroy() upon the returned value afterwards.
+ *
+ * @param p Policy within which to validate mls_range_string.
+ * @param mls_range_string Pointer to a string representing a valid
+ * MLS range.
+ *
+ * @return A filled in MLS range structure, or NULL upon error.
+ */
+ extern apol_mls_range_t *apol_mls_range_create_from_string(const apol_policy_t * p, const char *mls_range_string);
+
+/**
+ * Take a literal MLS range string (e.g.,
+ * <b>S0:C0.C10-S1:C0.C127</b>), fill in a newly allocated
+ * apol_mls_range_t and return it. The category portions of the
+ * levels will <strong>not</strong> be expanded (i.e., dots will not
+ * be resolved); likewise there is no check that the high level
+ * dominates the low. The caller must call apol_mls_range_destroy()
+ * upon the returned value afterwards.
+ *
+ * Because this function creates a range without the benefit of a
+ * policy, its levels are "incomplete" and thus most operations will
+ * fail. Call apol_mls_range_convert() to make a literal MLS range
+ * complete, so that it can be used in all functions.
+ *
+ * @param mls_range_string Pointer to a string representing a
+ * (possibly invalid) MLS range.
+ *
+ * @return A filled in MLS range structure, or NULL upon error.
+ */
+ extern apol_mls_range_t *apol_mls_range_create_from_literal(const char *mls_range_string);
+
+/**
+ * Create a new apol_mls_range_t and initialize it with a
+ * qpol_mls_range_t. The caller must call apol_mls_range_destroy()
+ * upon the return value afterwards.
+ *
+ * @param p Policy from which the qpol_mls_range_t was obtained.
+ * @param qpol_range The libqpol range for which to create a new
+ * apol range. This range will not be altered by this call.
+ *
+ * @return A MLS range structure initialized to the value of
+ * qpol_range, or NULL upon error.
+ */
+ extern apol_mls_range_t *apol_mls_range_create_from_qpol_mls_range(const apol_policy_t * p,
+ const qpol_mls_range_t * qpol_range);
+
+/**
+ * Deallocate all memory associated with a MLS range structure and
+ * then set it to NULL. This function does nothing if the range is
+ * already NULL.
+ *
+ * @param range Reference to a MLS range structure to destroy.
+ */
+ extern void apol_mls_range_destroy(apol_mls_range_t ** range);
+
+/**
+ * Set the low level component of a MLS range structure. This
+ * function takes ownership of the level, such that the caller must
+ * not modify nor destroy it afterwards. It is legal to pass in the
+ * same pointer for the range's low and high level.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param range MLS range to modify.
+ * @param level New low level for range, or NULL to unset this field.
+ *
+ * @return 0 on success or < 0 on failure.
+ */
+ extern int apol_mls_range_set_low(const apol_policy_t * p, apol_mls_range_t * range, apol_mls_level_t * level);
+
+/**
+ * Set the high level component of a MLS range structure. This
+ * function takes ownership of the level, such that the caller must
+ * not modify nor destroy it afterwards. It is legal to pass in the
+ * same pointer for the range's low and high level.
+ *
+ * @param p Error reporting handler, or NULL to use default handler.
+ * @param range MLS range to modify.
+ * @param level New high level for range, or NULL to unset this field.
+ *
+ * @return 0 on success or < 0 on failure.
+ */
+ extern int apol_mls_range_set_high(const apol_policy_t * p, apol_mls_range_t * range, apol_mls_level_t * level);
+
+/**
+ * Get the low level component of a MLS range structure.
+ *
+ * @param range MLS range to query.
+ *
+ * @return Low level, or NULL upon error or if not yet set. Do not
+ * modify the return value.
+ */
+ extern const apol_mls_level_t *apol_mls_range_get_low(const apol_mls_range_t * range);
+
+/**
+ * Get the high level component of a MLS range structure.
+ *
+ * @param range MLS range to query.
+ *
+ * @return High level, or NULL upon error or if not yet set. Do not
+ * modify the return value.
+ */
+ extern const apol_mls_level_t *apol_mls_range_get_high(const apol_mls_range_t * range);
+
+/**
+ * Compare two ranges, determining if one matches the other. The
+ * fifth parameter gives how to match the ranges. For APOL_QUERY_SUB,
+ * if search is a subset of target. For APOL_QUERY_SUPER, if search
+ * is a superset of target. Other valid compare types are
+ * APOL_QUERY_EXACT and APOL_QUERY_INTERSECT. If a range is not valid
+ * according to the policy then this function returns -1. If search
+ * is NULL then comparison always succeeds.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param target Target MLS range to compare.
+ * @param search Source MLS range to compare.
+ * @param range_compare_type Specifies how to compare the ranges.
+ *
+ * @return 1 If comparison succeeds, 0 if not; -1 on error.
+ */
+ extern int apol_mls_range_compare(const apol_policy_t * p,
+ const apol_mls_range_t * target, const apol_mls_range_t * search,
+ unsigned int range_compare_type);
+
+/**
+ * Determine if a range completely contains a subrange given a certain
+ * policy. If a range is not valid according to the policy then this
+ * function returns -1.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param range Parent range to compare.
+ * @param subrange Child range to which compare.
+ *
+ * @return 1 If comparison succeeds, 0 if not; -1 on error.
+ */
+ extern int apol_mls_range_contain_subrange(const apol_policy_t * p, const apol_mls_range_t * range,
+ const apol_mls_range_t * subrange);
+/**
+ * Given a range, determine if it is legal according to the supplied
+ * policy. This function will convert from aliases to canonical forms
+ * as necessary.
+ *
+ * @param p Policy within which to look up MLS information.
+ * @param range Range to check.
+ *
+ * @return 1 If range is legal, 0 if not; -1 on error.
+ */
+ extern int apol_mls_range_validate(const apol_policy_t * p, const apol_mls_range_t * range);
+
+/**
+ * Given a range, return a vector of levels (type apol_mls_level_t *)
+ * that constitutes that range. The vector will be sorted in policy order.
+ *
+ * @param p Policy from which the level and category definitions reside.
+ * @param range Range to expand.
+ *
+ * @return Vector of levels, or NULL upon error. The caller is
+ * responsible for calling apol_vector_destroy() upon the returned
+ * value, passing apol_mls_level_free() as the second parameter.
+ */
+ extern apol_vector_t *apol_mls_range_get_levels(const apol_policy_t * p, const apol_mls_range_t * range);
+
+/**
+ * Creates a string containing the textual representation of
+ * a MLS range.
+ *
+ * @param p Policy from which the MLS range is a member. If NULL,
+ * then attempt to treat the range's levels as incomplete levels (as
+ * per apol_mls_level_create_from_literal()).
+ * @param range MLS range to render.
+ *
+ * @return A newly allocated string, or NULL upon error. The caller
+ * is responsible for calling free() upon the return value.
+ */
+ extern char *apol_mls_range_render(const apol_policy_t * p, const apol_mls_range_t * range);
+
+/**
+ * Given a range, convert any literal MLS levels within it (as per
+ * apol_mls_level_convert()) to a complete level. If the range has no
+ * levels or has no literal levels then do nothing.
+ *
+ * @param p Policy containing category information.
+ * @param range Range to convert.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_mls_range_convert(const apol_policy_t * p, apol_mls_range_t * range);
+
+/**
+ * Determine if the range contains any literal levels. (Levels that
+ * have been converted are still considered literal.)
+ *
+ * @param range Range to query.
+ *
+ * @return > 0 value if the range has a literal level, 0 if not, < 0
+ * if unknown or upon error.
+ */
+ extern int apol_mls_range_is_literal(const apol_mls_range_t * range);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_MLS_RANGE_H */
diff --git a/libapol/include/apol/netcon-query.h b/libapol/include/apol/netcon-query.h
new file mode 100644
index 0000000..b74b229
--- /dev/null
+++ b/libapol/include/apol/netcon-query.h
@@ -0,0 +1,364 @@
+/**
+ * @file
+ * Public Interface for querying portcons, netifcons, and nodecons of
+ * a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_NETCON_QUERY_H
+#define APOL_NETCON_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include "context-query.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_portcon_query apol_portcon_query_t;
+ typedef struct apol_netifcon_query apol_netifcon_query_t;
+ typedef struct apol_nodecon_query apol_nodecon_query_t;
+
+/******************** portcon queries ********************/
+
+/**
+ * Execute a query against all portcons within the policy. The
+ * returned portcons will be unordered.
+ *
+ * @param p Policy within which to look up portcons.
+ * @param po Structure containing parameters for query. If this is
+ * NULL then return all portcons.
+ * @param v Reference to a vector of qpol_portcon_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_portcon_get_by_query(const apol_policy_t * p, const apol_portcon_query_t * po, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new portcon query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all portcons within the policy. The caller must call
+ * apol_portcon_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized portcon query structure, or NULL upon error.
+ */
+ extern apol_portcon_query_t *apol_portcon_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced portcon
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param po Reference to a portcon query structure to destroy.
+ */
+ extern void apol_portcon_query_destroy(apol_portcon_query_t ** po);
+
+/**
+ * Set a portcon query to return only portcons that use this protocol.
+ *
+ * @param p Policy handler, to report errors.
+ * @param po Portcon query to set.
+ * @param proto Limit query to only portcons with this protocol, or
+ * negative to unset this field.
+ *
+ * @return Always 0.
+ */
+ extern int apol_portcon_query_set_protocol(const apol_policy_t * p, apol_portcon_query_t * po, int proto);
+
+/**
+ * Set a portcon query to return only portcons with this as their low
+ * port.
+ *
+ * @param p Policy handler, to report errors.
+ * @param po Portcon query to set.
+ * @param low Limit query to only portcons with this low port, or
+ * negative to unset this field.
+ *
+ * @return Always 0.
+ */
+ extern int apol_portcon_query_set_low(const apol_policy_t * p, apol_portcon_query_t * po, int low);
+
+/**
+ * Set a portcon query to return only portcons with this as their high
+ * port.
+ *
+ * @param p Policy handler, to report errors.
+ * @param po Portcon query to set.
+ * @param high Limit query to only portcons with this high port, or
+ * negative to unset this field.
+ *
+ * @return Always 0.
+ */
+ extern int apol_portcon_query_set_high(const apol_policy_t * p, apol_portcon_query_t * po, int high);
+
+/**
+ * Set a portcon query to return only portcons matching a context.
+ * This function takes ownership of the context, such that the caller
+ * must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param po Portcon query to set.
+ * @param context Limit query to only portcons matching this context,
+ * or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_portcon_query_set_context(const apol_policy_t * p,
+ apol_portcon_query_t * po, apol_context_t * context, unsigned int range_match);
+
+/**
+ * Creates a string containing the textual representation of
+ * a portcon type.
+ * @param p Reference to a policy.
+ * @param portcon Reference to the portcon statement to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_portcon_render(const apol_policy_t * p, const qpol_portcon_t * portcon);
+
+/******************** netifcon queries ********************/
+
+/**
+ * Execute a query against all netifcons within the policy. The
+ * returned netifcons will be unordered.
+ *
+ * @param p Policy within which to look up netifcons.
+ * @param n Structure containing parameters for query. If this is
+ * NULL then return all netifcons.
+ * @param v Reference to a vector of qpol_netifcon_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards,. This will be set to NULL upon
+ * no results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_netifcon_get_by_query(const apol_policy_t * p, const apol_netifcon_query_t * n, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new netifcon query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all netifcons within the policy. The caller must call
+ * apol_netifcon_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized netifcon query structure, or NULL upon
+ * error.
+ */
+ extern apol_netifcon_query_t *apol_netifcon_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced netifcon
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param n Reference to a netifcon query structure to destroy.
+ */
+ extern void apol_netifcon_query_destroy(apol_netifcon_query_t ** n);
+
+/**
+ * Set a netifcon query to return only netifcons that use this device.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Netifcon query to set.
+ * @param dev Limit query to only netifcons that use this device, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_netifcon_query_set_device(const apol_policy_t * p, apol_netifcon_query_t * n, const char *dev);
+
+/**
+ * Set a netifcon query to return only netifcons matching this context
+ * for its interface. This function takes ownership of the context,
+ * such that the caller must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Netifcon query to set.
+ * @param context Limit query to only netifcon matching this context
+ * for its interface, or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_netifcon_query_set_if_context(const apol_policy_t * p,
+ apol_netifcon_query_t * n, apol_context_t * context,
+ unsigned int range_match);
+
+/**
+ * Set a netifcon query to return only netifcons matching this context
+ * for its messages. This function takes ownership of the context,
+ * such that the caller must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Netifcon query to set.
+ * @param context Limit query to only netifcon matching this context
+ * for its messages, or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_netifcon_query_set_msg_context(const apol_policy_t * p,
+ apol_netifcon_query_t * n, apol_context_t * context,
+ unsigned int range_match);
+
+/**
+ * Creates a string containing the textual representation of
+ * a netifcon type.
+ * @param p Reference to a policy.
+ * @param netifcon Reference to the netifcon statement to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_netifcon_render(const apol_policy_t * p, const qpol_netifcon_t * netifcon);
+
+/******************** nodecon queries ********************/
+
+/**
+ * Execute a query against all nodecons within the policy. The
+ * returned nodecons will be unordered.
+ *
+ * @param p Policy within which to look up nodecons.
+ * @param n Structure containing parameters for query. If this is
+ * NULL then return all nodecons.
+ * @param v Reference to a vector of qpol_nodecon_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_nodecon_get_by_query(const apol_policy_t * p, const apol_nodecon_query_t * n, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new nodecon query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all nodecons within the policy. The caller must call
+ * apol_nodecon_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized nodecon query structure, or NULL upon
+ * error.
+ */
+ extern apol_nodecon_query_t *apol_nodecon_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced nodecon
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param n Reference to a nodecon query structure to destroy.
+ */
+ extern void apol_nodecon_query_destroy(apol_nodecon_query_t ** n);
+
+/**
+ * Set a nodecon query to return only nodecons with this protocol,
+ * either IPv4 or IPv6.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Nodecon query to set.
+ * @param proto Limit query to only this protocol, either QPOL_IPV4 or
+ * QPOL_IPV6, or a negative value to unset this field.
+ *
+ * @return 0 if protocol was valid, -1 on error.
+ */
+ extern int apol_nodecon_query_set_protocol(const apol_policy_t * p, apol_nodecon_query_t * n, int proto);
+
+/**
+ * Set a nodecon query to return only nodecons with this address. If
+ * the protocol is QPOL_IPV4 then only the first element of the
+ * address array is used, for QPOL_IPV6 all four are used.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Nodecon query to set.
+ * @param addr Array of no more than four elements representing the
+ * address, or NULL to unset this field. This function will make a
+ * copy of the array.
+ * @param proto Format of address, either QPOL_IPV4 or QPOL_IPV6.
+ * This parameter is ignored if addr is NULL.
+ *
+ * @return 0 if protocol was valid, -1 on error.
+ */
+ extern int apol_nodecon_query_set_addr(const apol_policy_t * p, apol_nodecon_query_t * n, uint32_t * addr, int proto);
+
+/**
+ * Set a nodecon query to return only nodecons with this netmask. If
+ * the protocol is QPOL_IPV4 then only the first element of the mask
+ * array is used, for QPOL_IPV6 all four are used.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Nodecon query to set.
+ * @param mask Array of no more than four elements representing the
+ * netmask, or NULL to unset this field. This function will make a
+ * copy of the array.
+ * @param proto Format of mask, either QPOL_IPV4 or QPOL_IPV6. This
+ * parameter is ignored if mask is NULL.
+ *
+ * @return 0 if protocol was valid, -1 on error.
+ */
+ extern int apol_nodecon_query_set_mask(const apol_policy_t * p, apol_nodecon_query_t * n, uint32_t * mask, int proto);
+
+/**
+ * Set a nodecon query to return only nodecons matching this context.
+ * This function takes ownership of the context, such that the caller
+ * must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param n Nodecon query to set.
+ * @param context Limit query to only nodecons matching this context,
+ * or NULL to unset this field.
+ * @param range_match Specifies how to match the MLS range within the
+ * context. This must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if context is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_nodecon_query_set_context(const apol_policy_t * p,
+ apol_nodecon_query_t * n, apol_context_t * context, unsigned int range_match);
+
+/**
+ * Creates a string containing the textual representation of
+ * a nodecon type.
+ * @param p Reference to a policy.
+ * @param nodecon Reference to the nodecon statement to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_nodecon_render(const apol_policy_t * p, const qpol_nodecon_t * nodecon);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_NETCON_QUERY_H */
diff --git a/libapol/include/apol/perm-map.h b/libapol/include/apol/perm-map.h
new file mode 100644
index 0000000..ea2c0e7
--- /dev/null
+++ b/libapol/include/apol/perm-map.h
@@ -0,0 +1,137 @@
+/**
+ * @file
+ *
+ * Permission mapping routines for libapol. These maps assoicate all
+ * object class permissions with read, write, read&write, and none
+ * access. These maps are used, for example, by an information flow
+ * analysis.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2003-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_PERMMAP_H
+#define APOL_PERMMAP_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+
+#define APOL_PERMMAP_MAX_WEIGHT 10
+#define APOL_PERMMAP_MIN_WEIGHT 1
+
+#define APOL_PERMMAP_UNMAPPED 0x00 /* defined object/perm, but no map */
+#define APOL_PERMMAP_READ 0x01
+#define APOL_PERMMAP_WRITE 0x02
+#define APOL_PERMMAP_BOTH (APOL_PERMMAP_READ | APOL_PERMMAP_WRITE)
+#define APOL_PERMMAP_NONE 0x10
+
+/**
+ * Read a permission map from a file into a policy. If there is a
+ * non-fatal error while loading (e.g., file declared an object class
+ * that does not exist within the policy) then generate a warning
+ * string and send it to the error handler stored within the policy.
+ *
+ * If a permission map was already loaded, then the existing one will
+ * be destroyed.
+ *
+ * @param p Policy to which store permission map.
+ * @param filename Name of file containing permission map.
+ *
+ * @return 0 on success, > 0 on success with warnings, < 0 on error.
+ */
+ extern int apol_policy_open_permmap(apol_policy_t * p, const char *filename);
+
+/**
+ * @deprecated Use apol_policy_open_permmap().
+ */
+ extern int apol_permmap_load(apol_policy_t * p, const char *filename) __attribute__ ((deprecated));
+
+/**
+ * Write the contents of permission map to a file. Any existing file
+ * will be overwritten.
+ *
+ * @param p Policy containing permission map.
+ * @param filename Destination filename.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_policy_save_permmap(const apol_policy_t * p, const char *filename);
+
+/**
+ * @deprecated Use apol_policy_save_permmap().
+ */
+ extern int apol_permmap_save(apol_policy_t * p, const char *filename) __attribute__ ((deprecated));
+
+/**
+ * Given a class and permission name, look up that permission mapping
+ * within a policy's permission map. Set the reference variables map
+ * and weight to the mapping.
+ *
+ * @param p Policy containing permission map.
+ * @param class_name Name of class to find.
+ * @param perm_name Permission within class to find.
+ * @param map Location to store mapping, one of APOL_PERMMAP_UNMAPPED,
+ * etc.
+ * @param weight Weight of this permission, a value between
+ * APOL_PERMMAP_MIN_WEIGHT and APOL_PERMMAP_MAX_WEIGHT, inclusive.
+ *
+ * @return 0 if class and permission were found, < 0 on error or if
+ * not found.
+ */
+ extern int apol_policy_get_permmap(const apol_policy_t * p, const char *class_name, const char *perm_name, int *map,
+ int *weight);
+
+/**
+ * @deprecated Use apol_policy_get_permmap().
+ */
+ extern int apol_permmap_get(apol_policy_t * p, const char *class_name, const char *perm_name, int *map, int *weight)
+ __attribute__ ((deprecated));
+
+/**
+ * Given a class and permission name, set that permission's map and
+ * weight within the policy's permission map.
+ *
+ * @param p Policy containing permission map.
+ * @param class_name Name of class to find.
+ * @param perm_name Permission within class to find.
+ * @param map New map value, one of APOL_PERMMAP_UNMAPPED, etc.
+ * @param weight New weight of this permission. If the value will be
+ * clamped to be between APOL_PERMMAP_MIN_WEIGHT and
+ * APOL_PERMMAP_MAX_WEIGHT, inclusive.
+ *
+ * @return 0 if permission map was changed, < 0 on error or if not
+ * found.
+ */
+ extern int apol_policy_set_permmap(apol_policy_t * p, const char *class_name, const char *perm_name, int map, int weight);
+
+/**
+ * @deprecated Use apol_policy_set_permmap().
+ */
+ extern int apol_permmap_set(apol_policy_t * p, const char *class_name, const char *perm_name, int map, int weight)
+ __attribute__ ((deprecated));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*APOL_PERMMAP_H */
diff --git a/libapol/include/apol/permissive-query.h b/libapol/include/apol/permissive-query.h
new file mode 100644
index 0000000..988ea47
--- /dev/null
+++ b/libapol/include/apol/permissive-query.h
@@ -0,0 +1,104 @@
+/**
+ * @file
+ *
+ * Routines to query permissive types in policy.
+ *
+ * @author Steve Lawrence slawrence@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_PERMISSIVE_QUERY_H
+#define APOL_PERMISSIVE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_permissive_query apol_permissive_query_t;
+
+/**
+ * Execute a query against all permissive types within the policy. The results
+ * will only contain permissive types, not aliases nor attributes.
+ *
+ * @param p Policy within which to look up permissive types.
+ * @param t Structure containing parameters for query. If this is
+ * NULL then return all permissive types.
+ * @param v Reference to a vector of qpol_permissive_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_permissive_get_by_query(const apol_policy_t * p, apol_permissive_query_t * t, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new permissive query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all permissive types within the policy. The caller must call
+ * apol_permissive_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized permissive query structure, or NULL upon error.
+ */
+ extern apol_permissive_query_t *apol_permissive_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced permissive query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param t Reference to a permissive query structure to destroy.
+ */
+ extern void apol_permissive_query_destroy(apol_permissive_query_t ** t);
+
+/**
+ * Set a permissive query to return only permissive types that match this name. This function
+ * duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Permissive query to set.
+ * @param name Limit query to only permissive types with this name, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_permissive_query_set_name(const apol_policy_t * p, apol_permissive_query_t * t, const char *name);
+
+/**
+ * Set a permissive query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ * Matching will occur against the permissive type name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Permissive query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_permissive_query_set_regex(const apol_policy_t * p, apol_permissive_query_t * t, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/polcap-query.h b/libapol/include/apol/polcap-query.h
new file mode 100644
index 0000000..b8f7d6b
--- /dev/null
+++ b/libapol/include/apol/polcap-query.h
@@ -0,0 +1,103 @@
+/**
+ * @file
+ *
+ * Routines to query policy capabilities in policy.
+ *
+ * @author Steve Lawrence slawrence@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_POLCAP_QUERY_H
+#define APOL_POLCAP_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_polcap_query apol_polcap_query_t;
+
+/**
+ * Execute a query against all policy capabilities within the policy.
+ *
+ * @param p Policy within which to look up policy capabilities.
+ * @param t Structure containing parameters for query. If this is
+ * NULL then return all policy capabilities.
+ * @param v Reference to a vector of qpol_polcap_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_polcap_get_by_query(const apol_policy_t * p, apol_polcap_query_t * t, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new polcap query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all policy capabilities within the policy. The caller must call
+ * apol_polcap_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized polcap query structure, or NULL upon error.
+ */
+ extern apol_polcap_query_t *apol_polcap_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced polcap query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param t Reference to a polcap query structure to destroy.
+ */
+ extern void apol_polcap_query_destroy(apol_polcap_query_t ** t);
+
+/**
+ * Set a polcap query to return only policy capabilities that match this name. This function
+ * duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Polcap query to set.
+ * @param name Limit query to only policy capabilities with this name, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_polcap_query_set_name(const apol_policy_t * p, apol_polcap_query_t * t, const char *name);
+
+/**
+ * Set a polcap query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ * Matching will occur against the policy capability name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Polcap query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_polcap_query_set_regex(const apol_policy_t * p, apol_polcap_query_t * t, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/policy-path.h b/libapol/include/apol/policy-path.h
new file mode 100644
index 0000000..771fdf5
--- /dev/null
+++ b/libapol/include/apol/policy-path.h
@@ -0,0 +1,194 @@
+/**
+ * @file
+ *
+ * An opaque structure that represents a policy "path". A policy path
+ * may really be a base policy and a number of modules, thus a single
+ * string is not sufficient.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_POLICY_PATH_H
+#define APOL_POLICY_PATH_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "vector.h"
+
+ typedef struct apol_policy_path apol_policy_path_t;
+
+/**
+ * Type of policy this path represents - either a single path, for a
+ * monolithic policy, or a path + multiple modules for modular policy.
+ */
+ typedef enum apol_policy_path_type
+ {
+ APOL_POLICY_PATH_TYPE_MONOLITHIC = 0,
+ APOL_POLICY_PATH_TYPE_MODULAR
+ } apol_policy_path_type_e;
+
+/**
+ * Create a policy path from scratch. The resulting object represents
+ * the file or files needed to load a policy.
+ *
+ * @param path_type Type of policy to represent.
+ * @param path Primary path name. For modular policies this is the
+ * base policy's path.
+ * @param modules Vector of strings representing modules' paths. The
+ * vector can be NULL to mean no modules. This parameter is ignored
+ * if path_type is not APOL_POLICY_PATH_TYPE_MODULAR. The function
+ * will duplicate the vector and its contents.
+ *
+ * @return An apol_policy_path object, or NULL upon error.
+ */
+ extern apol_policy_path_t *apol_policy_path_create(apol_policy_path_type_e path_type, const char *path,
+ const apol_vector_t * modules);
+
+/**
+ * Create a policy path, initialized from another policy path. This
+ * function recursively duplicates all data within the original path.
+ *
+ * @param path Policy path to duplicate.
+ *
+ * @return An apol_policy_path object, or NULL upon error.
+ */
+ extern apol_policy_path_t *apol_policy_path_create_from_policy_path(const apol_policy_path_t * path);
+
+/**
+ * Create a policy path, initialize by the contents of a <em>policy
+ * path list</em> file. Call apol_policy_path_to_filename() to write
+ * a policy path list to disk.
+ *
+ * @param filename Name of the file containing a policy path list.
+ *
+ * @return An apol_policy_path object, or NULL upon error.
+ */
+ extern apol_policy_path_t *apol_policy_path_create_from_file(const char *filename);
+
+/**
+ * Create a policy path, initialized by a special path format string.
+ * Call apol_policy_path_to_string() to create this string.
+ *
+ * @param path_string String containing initialization data for the
+ * object.
+ *
+ * @return An apol_policy_path object, or NULL upon error.
+ */
+ extern apol_policy_path_t *apol_policy_path_create_from_string(const char *path_string);
+
+/**
+ * Destroy the referencened policy path object.
+ *
+ * @param path Policy path to destroy. The pointer will be set to
+ * NULL afterwards. (If pointer is already NULL then do nothing.)
+ */
+ extern void apol_policy_path_destroy(apol_policy_path_t ** path);
+
+/**
+ * Compare two policy paths, determining if one is different than the
+ * other. The returned value is stable, in that it may be used as the
+ * basis for sorting a list of policy paths. Monolithic policies are
+ * considered "less than" modular policies.
+ *
+ * @param a First policy path to compare.
+ * @param b Second policy path to compare.
+ *
+ * @return < 0 if path A is "less than" B, > 0 if A is "greater than"
+ * B, or 0 if equivalent or undeterminable.
+ */
+ extern int apol_policy_path_compare(const apol_policy_path_t * a, const apol_policy_path_t * b);
+
+/**
+ * Get the type of policy this path object represents.
+ *
+ * @param path Policy path object to query.
+ *
+ * @return Type of policy the object represents.
+ */
+ extern apol_policy_path_type_e apol_policy_path_get_type(const apol_policy_path_t * path);
+
+/**
+ * Get the primary path name from a path object. For monolithic
+ * policies this is the path to the policy. For modular policies this
+ * is the base policy path.
+ *
+ * @param path Policy path object to query.
+ *
+ * @return Primary path, or NULL upon error. Do not modify
+ * this string.
+ */
+ extern const char *apol_policy_path_get_primary(const apol_policy_path_t * path);
+
+/**
+ * Get the list of modules from a path object. This will be a vector
+ * of strings. It is an error to call this function for non-modular
+ * policies.
+ *
+ * @param path Policy path object to query.
+ *
+ * @return Vector of module paths, or NULL upon error. Do not modify
+ * this vector or its contents. Note that the vector could be empty.
+ */
+ extern const apol_vector_t *apol_policy_path_get_modules(const apol_policy_path_t * path);
+
+/**
+ * Write a human-readable <em>policy path list</em> to disk. This
+ * file describes a policy path and is suitable as input to
+ * apol_policy_path_create_from_file().
+ *
+ * @param path Policy path to write to disk.
+ * @param filename Name of the file to write policy path list. If the
+ * file already exists it will be overwritten.
+ *
+ * @return 0 on successful write, < 0 on error.
+ */
+ extern int apol_policy_path_to_file(const apol_policy_path_t * path, const char *filename);
+
+/**
+ * Encode a path object into a specially formatted string. The
+ * resulting string is suitable as input to
+ * apol_policy_path_create_from_string().
+ *
+ * @param path Policy path object to encode.
+ *
+ * @return Formatted string for the path object, or NULL upon error.
+ * The caller is responsible for calling free() upon the returned
+ * value.
+ */
+ extern char *apol_policy_path_to_string(const apol_policy_path_t * path);
+
+/**
+ * Determine if a file is a policy path list.
+ *
+ * @param filename Name of the file to test.
+ *
+ * @return > 0 if the file is a policy path list, 0 if it is not,
+ * and < 0 on error.
+ */
+ extern int apol_file_is_policy_path_list(const char *filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/policy-query.h b/libapol/include/apol/policy-query.h
new file mode 100644
index 0000000..315f70e
--- /dev/null
+++ b/libapol/include/apol/policy-query.h
@@ -0,0 +1,86 @@
+/**
+ * @file
+ *
+ * Routines to query parts of a policy. For each component and rule
+ * there is a query structure to specify the details of the query.
+ * Analyses are also included by this header file.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_POLICY_QUERY_H
+#define APOL_POLICY_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Many libapol queries act upon MLS contexts. Use these defines to
+ * specify set operations upon contexts.
+ */
+#define APOL_QUERY_SUB 0x02 /**< The range specified by the query is a subset of the target range */
+#define APOL_QUERY_SUPER 0x04 /**< The range specified by the query is a superset of the target range */
+#define APOL_QUERY_EXACT (APOL_QUERY_SUB|APOL_QUERY_SUPER) /**< The range specified by the query matches the target range exactly. */
+#define APOL_QUERY_INTERSECT 0x08 /* query overlaps any part of rule range */
+#define APOL_QUERY_FLAGS \
+ (APOL_QUERY_SUB | APOL_QUERY_SUPER | APOL_QUERY_EXACT | \
+ APOL_QUERY_INTERSECT)
+
+/* The AV rule search and TE rule search use these flags when
+ * specifying what kind of symbol is being searched. Strings are
+ * normally interpreted either as a type or as an attribute; the behavior
+ * can be changed to use only types or only attributes.
+ */
+#define APOL_QUERY_SYMBOL_IS_TYPE 0x01
+#define APOL_QUERY_SYMBOL_IS_ATTRIBUTE 0x02
+
+#include <qpol/policy.h>
+
+#include "type-query.h"
+#include "class-perm-query.h"
+#include "role-query.h"
+#include "user-query.h"
+#include "bool-query.h"
+#include "isid-query.h"
+#include "mls-query.h"
+#include "netcon-query.h"
+#include "fscon-query.h"
+#include "context-query.h"
+#include "permissive-query.h"
+#include "polcap-query.h"
+
+#include "avrule-query.h"
+#include "terule-query.h"
+#include "condrule-query.h"
+#include "rbacrule-query.h"
+#include "range_trans-query.h"
+#include "constraint-query.h"
+
+#include "domain-trans-analysis.h"
+#include "infoflow-analysis.h"
+#include "relabel-analysis.h"
+#include "types-relation-analysis.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/policy.h b/libapol/include/apol/policy.h
new file mode 100644
index 0000000..7b26af8
--- /dev/null
+++ b/libapol/include/apol/policy.h
@@ -0,0 +1,166 @@
+/**
+ * @file
+ *
+ * Public interface for SELinux policies. This function declares
+ * apol_policy, a structure that groups a qpol_policy with other
+ * structures needed by libapol. Almost all setools files will need
+ * to #include this header.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_POLICY_H
+#define APOL_POLICY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy-path.h"
+#include <stdarg.h>
+#include <qpol/policy.h>
+
+ typedef struct apol_policy apol_policy_t;
+
+ typedef void (*apol_callback_fn_t) (void *varg, const apol_policy_t * p, int level, const char *fmt, va_list argp);
+
+/**
+ * When creating an apol_policy, load all components except rules
+ * (both AV and TE rules). For modular policies, this affects both
+ * the base policy and subsequent modules.
+ * @deprecated use QPOL_POLICY_OPTION_NO_RULES instead
+ */
+#define APOL_POLICY_OPTION_NO_RULES QPOL_POLICY_OPTION_NO_RULES
+
+/**
+ * Create a new apol_policy initialized from one or more policy files.
+ *
+ * @param path Policy path object specifying which policy file or
+ * files to load.
+ * @param options Bitfield specifying options for the returned policy.
+ * Valid options are QPOL_POLICY_OPTION_* from <qpol/policy.h>.
+ * @param msg_callback Callback to invoke as errors/warnings are
+ * generated. If NULL, then write messages to standard error.
+ * @param varg Value to be passed as the first parameter to the
+ * callback function.
+ *
+ * @return A newly allocated policy that may be used for analysis, or
+ * NULL upon error. The caller is responsible for calling
+ * apol_policy_destroy() upon the returned value afterwards.
+ */
+ extern apol_policy_t *apol_policy_create_from_policy_path(const apol_policy_path_t * path, const int options,
+ apol_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Deallocate all memory associated with a policy, including all
+ * auxillary data structures, and then set it to NULL. Does nothing
+ * if the pointer is already NULL.
+ *
+ * @param policy Policy to destroy, if not already NULL.
+ */
+ extern void apol_policy_destroy(apol_policy_t ** policy);
+
+/**
+ * Given a policy, return the policy type. This will be one of
+ * QPOL_POLICY_KERNEL_SOURCE, QPOL_POLICY_KERNEL_BINARY, or
+ * QPOL_POLICY_MODULE_BINARY. (You will need to #include
+ * <qpol/policy.h> to get these definitions.)
+ *
+ * @param policy Policy to which check.
+ *
+ * @return The policy type, or < 0 upon error.
+ */
+ extern int apol_policy_get_policy_type(const apol_policy_t * policy);
+
+/**
+ * Given a policy, return a pointer to the underlying qpol_policy.
+ * This is needed, for example, to access details of particulary qpol
+ * components.
+ *
+ * @param policy Policy containing qpol policy.
+ *
+ * @return Pointer to underlying qpol policy, or NULL on error. Do
+ * not free() or otherwise destroy this pointer.
+ */
+ extern qpol_policy_t *apol_policy_get_qpol(const apol_policy_t * policy);
+
+/**
+ * Given a policy, return 1 if the policy within is MLS, 0 if not. If
+ * it cannot be determined or upon error, return < 0.
+ *
+ * @param p Policy to which check.
+ * @return 1 if policy is MLS, 0 if not, < 0 upon error.
+ */
+ extern int apol_policy_is_mls(const apol_policy_t * p);
+
+/**
+ * Given a policy, allocate and return a string that describes the
+ * policy (policy version, source/binary, mls/non-mls).
+ *
+ * @param p Policy to check.
+ * @return String that describes policy, or NULL upon error. The
+ * caller must free() this afterwards.
+ */
+ extern char *apol_policy_get_version_type_mls_str(const apol_policy_t * p);
+
+#define APOL_MSG_ERR 1
+#define APOL_MSG_WARN 2
+#define APOL_MSG_INFO 3
+
+/**
+ * Write a message to the callback stored within an apol error
+ * handler. If the msg_callback field is empty, then the default
+ * message callback will be used.
+ *
+ * @param p Error reporting handler. If NULL then write message to
+ * stderr.
+ * @param level Severity of message, one of APOL_MSG_ERR,
+ * APOL_MSG_WARN, or APOL_MSG_INFO.
+ * @param fmt Format string to print, using syntax of printf(3).
+ */
+ extern void apol_handle_msg(const apol_policy_t * p, int level, const char *fmt, ...);
+
+ __attribute__ ((format(printf, 3, 4))) extern void apol_handle_msg(const apol_policy_t * p, int level, const char *fmt,
+ ...);
+
+/**
+ * Invoke a apol_policy_t's callback for an error, passing it a format
+ * string and arguments.
+ */
+#define ERR(p, format, ...) apol_handle_msg(p, APOL_MSG_ERR, format, __VA_ARGS__)
+
+/**
+ * Invoke a apol_policy_t's callback for a warning, passing it a
+ * format string and arguments.
+ */
+#define WARN(p, format, ...) apol_handle_msg(p, APOL_MSG_WARN, format, __VA_ARGS__)
+
+/**
+ * Invoke a apol_policy_t's callback for an informational messag,
+ * passing it a format string and arguments.
+ */
+#define INFO(p, format, ...) apol_handle_msg(p, APOL_MSG_INFO, format, __VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/range_trans-query.h b/libapol/include/apol/range_trans-query.h
new file mode 100644
index 0000000..e3113c5
--- /dev/null
+++ b/libapol/include/apol/range_trans-query.h
@@ -0,0 +1,198 @@
+/**
+ * @file
+ *
+ * Routines to query range transition rules of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_RANGE_TRANS_QUERY_H
+#define APOL_RANGE_TRANS_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mls_range.h"
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_range_trans_query apol_range_trans_query_t;
+
+/**
+ * Execute a query against all range transition rules within the
+ * policy.
+ *
+ * @param p Policy within which to look up terules.
+ * @param r Structure containing parameters for query. If this is
+ * NULL then return all range transitions.
+ * @param v Reference to a vector of qpol_range_trans_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon
+ * error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_range_trans_get_by_query(const apol_policy_t * p, const apol_range_trans_query_t * r, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new range trans query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all range transitions within the policy. The caller must
+ * call apol_range_trans_query_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized range trans structure, or NULL upon error.
+ */
+ extern apol_range_trans_query_t *apol_range_trans_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced range trans
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param r Reference to a range trans query structure to destroy.
+ */
+ extern void apol_range_trans_query_destroy(apol_range_trans_query_t ** r);
+
+/**
+ * Set a range trans query to return rules whose source symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans rule query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * source, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_range_trans_query_set_source(const apol_policy_t * p, apol_range_trans_query_t * r, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set a range trans query to return rules whose target symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * target, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_range_trans_query_set_target(const apol_policy_t * p, apol_range_trans_query_t * r, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set a range trans query to return rules whose object class matches
+ * symbol. If more than one class are appended to the query, the
+ * rule's class must be one of those appended. (I.e., the rule's
+ * class must be a member of the query's classes.) Pass a NULL to
+ * clear all classes. Note that this performs straight string
+ * comparison, ignoring the regex flag.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans query to set.
+ * @param obj_class Name of object class to add to search set, or NULL
+ * to clear all classes.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_range_trans_query_append_class(const apol_policy_t * p, apol_range_trans_query_t * r,
+ const char *obj_class);
+
+/**
+ * Set a range trans query to return only rules matching a MLS range.
+ * This function takes ownership of the range, such that the caller
+ * must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans query to set.
+ * @param range Limit query to only rules matching this range, or NULL
+ * to unset this field.
+ * @param range_match Specifies how to match a rules to a range. This
+ * must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if range is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_range_trans_query_set_range(const apol_policy_t * p,
+ apol_range_trans_query_t * r, apol_mls_range_t * range,
+ unsigned int range_match);
+
+/**
+ * Set a range trans query to treat the source symbol as any. That
+ * is, use the same symbol for either source or target of a rule.
+ * This flag does nothing if the source symbol is not set.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans rule query to set.
+ * @param is_any Non-zero to use source symbol for any field, 0 to
+ * keep source as only source.
+ *
+ * @return Always 0.
+ */
+ extern int apol_range_trans_query_set_source_any(const apol_policy_t * p, apol_range_trans_query_t * r, int is_any);
+
+/**
+ * Set a range trans query to use regular expression searching for
+ * source and target types/attributes. Strings will be treated as
+ * regexes instead of literals. Matching will occur against the type
+ * name or any of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Range trans rule query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_range_trans_query_set_regex(const apol_policy_t * p, apol_range_trans_query_t * t, int is_regex);
+
+/**
+ * Render a range transition to a string.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+ */
+ extern char *apol_range_trans_render(const apol_policy_t * policy, const qpol_range_trans_t * rule);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/rbacrule-query.h b/libapol/include/apol/rbacrule-query.h
new file mode 100644
index 0000000..61822ee
--- /dev/null
+++ b/libapol/include/apol/rbacrule-query.h
@@ -0,0 +1,279 @@
+/**
+ * @file
+ *
+ * Routines to query (role) allow and role_transition rules of a
+ * policy. This does not include access vector's allow rules, which
+ * are found in avrule-query.h.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_RBACRULE_QUERY_H
+#define APOL_RBACRULE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_role_allow_query apol_role_allow_query_t;
+ typedef struct apol_role_trans_query apol_role_trans_query_t;
+
+/******************** (role) allow queries ********************/
+
+/**
+ * Execute a query against all (role) allow rules within the policy.
+ *
+ * @param p Policy within which to look up allow rules.
+ * @param r Structure containing parameters for query. If this is
+ * NULL then return all allow rules.
+ * @param v Reference to a vector of qpol_role_allow_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_role_allow_get_by_query(const apol_policy_t * p, const apol_role_allow_query_t * r, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new role allow query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all (role) allows within the policy. The caller must
+ * call apol_role_allow_query_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized role allow query structure, or NULL upon
+ * error.
+ */
+ extern apol_role_allow_query_t *apol_role_allow_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced role allow
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param r Reference to a role allow query structure to destroy.
+ */
+ extern void apol_role_allow_query_destroy(apol_role_allow_query_t ** r);
+
+/**
+ * Set a role allow query to return rules with a particular source
+ * role.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role allow query to set.
+ * @param role Limit query to rules with this role as their source, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_allow_query_set_source(const apol_policy_t * p, apol_role_allow_query_t * r, const char *role);
+
+/**
+ * Set a role allow query to return rules with a particular target
+ * role. This field is ignored if
+ * apol_role_allow_query_set_source_any() is set to non-zero.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role allow query to set.
+ * @param role Limit query to rules with this role as their target, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_allow_query_set_target(const apol_policy_t * p, apol_role_allow_query_t * r, const char *role);
+
+/**
+ * Set a role allow query to treat the source role as any. That is,
+ * use the same symbol for either source or target of a (role) allow
+ * rule. This flag does nothing if the source role is not set.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role allow query to set.
+ * @param is_any Non-zero to use source symbol for any field, 0 to
+ * keep source as only source.
+ *
+ * @return Always 0.
+ */
+ extern int apol_role_allow_query_set_source_any(const apol_policy_t * p, apol_role_allow_query_t * r, int is_any);
+
+/**
+ * Set a role allow query to use regular expression searching for
+ * source and target fields. Strings will be treated as regexes
+ * instead of literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role allow query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_role_allow_query_set_regex(const apol_policy_t * p, apol_role_allow_query_t * r, int is_regex);
+
+/**
+ * Render a role allow rule to a string.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+ */
+ extern char *apol_role_allow_render(const apol_policy_t * policy, const qpol_role_allow_t * rule);
+
+/******************** role_transition queries ********************/
+
+/**
+ * Execute a query against all role_transition rules within the
+ * policy.
+ *
+ * @param p Policy within which to look up role_transition rules.
+ * @param r Structure containing parameters for query. If this is
+ * NULL then return all role_transition rules.
+ * @param v Reference to a vector of qpol_role_trans_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_role_trans_get_by_query(const apol_policy_t * p, const apol_role_trans_query_t * r, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new role trans query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all role_transitions within the policy. The caller must
+ * call apol_role_trans_query_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized role trans query structure, or NULL upon
+ * error.
+ */
+ extern apol_role_trans_query_t *apol_role_trans_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced role trans
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param r Reference to a role trans query structure to destroy.
+ */
+ extern void apol_role_trans_query_destroy(apol_role_trans_query_t ** r);
+
+/**
+ * Set a role trans query to return rules with a particular source
+ * role.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role trans query to set.
+ * @param role Limit query to rules with this role as their source, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_trans_query_set_source(const apol_policy_t * p, apol_role_trans_query_t * r, const char *role);
+
+/**
+ * Set a role trans query to return rules with a particular target
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role trans query to set.
+ * @param symbol Limit query to rules with this type or attribute as
+ * their target, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_trans_query_set_target(const apol_policy_t * p, apol_role_trans_query_t * r, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set a role trans query to return rules with a particular default
+ * role. This field is ignored if
+ * apol_role_trans_query_set_source_any() is set to non-zero.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role trans query to set.
+ * @param role Limit query to rules with this role as their default, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_trans_query_set_default(const apol_policy_t * p, apol_role_trans_query_t * r, const char *role);
+
+/**
+ * Set a role trans query to treat the source role as any. That is,
+ * use the same symbol for either source or default of a
+ * role_transition rule. This flag does nothing if the source role is
+ * not set. Note that a role_transition's target is a type, so thus
+ * this flag does not affect its searching.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role trans query to set.
+ * @param is_any Non-zero to use source symbol for source or default
+ * field, 0 to keep source as only source.
+ *
+ * @return Always 0.
+ */
+ extern int apol_role_trans_query_set_source_any(const apol_policy_t * p, apol_role_trans_query_t * r, int is_any);
+
+/**
+ * Set a role trans query to use regular expression searching for
+ * source, target, and default fields. Strings will be treated as
+ * regexes instead of literals. For the target type, matching will
+ * occur against the type name or any of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role trans query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_role_trans_query_set_regex(const apol_policy_t * p, apol_role_trans_query_t * r, int is_regex);
+
+/**
+ * Render a role_transition rule to a string.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param rule The rule to render.
+ *
+ * @return A newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+ */
+ extern char *apol_role_trans_render(const apol_policy_t * policy, const qpol_role_trans_t * rule);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/relabel-analysis.h b/libapol/include/apol/relabel-analysis.h
new file mode 100644
index 0000000..1aed049
--- /dev/null
+++ b/libapol/include/apol/relabel-analysis.h
@@ -0,0 +1,258 @@
+/**
+ * @file
+ *
+ * Routines to perform a direct relabelling analysis.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2005-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_RELABEL_ANALYSIS_H
+#define APOL_RELABEL_ANALYSIS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+/* defines for direction flag */
+#define APOL_RELABEL_DIR_TO 0x01
+#define APOL_RELABEL_DIR_FROM 0x02
+#define APOL_RELABEL_DIR_BOTH (APOL_RELABEL_DIR_TO|APOL_RELABEL_DIR_FROM)
+#define APOL_RELABEL_DIR_SUBJECT 0x04
+
+ typedef struct apol_relabel_analysis apol_relabel_analysis_t;
+ typedef struct apol_relabel_result apol_relabel_result_t;
+ typedef struct apol_relabel_result_pair apol_relabel_result_pair_t;
+
+/******************** functions to do relabel analysis ********************/
+
+/**
+ * Execute a relabel analysis against a particular policy.
+ *
+ * @param p Policy within which to look up allow rules.
+ * @param r A non-NULL structure containing parameters for analysis.
+ * @param v Reference to a vector of apol_relabel_result_t. The
+ * vector will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_do(const apol_policy_t * p, apol_relabel_analysis_t * r, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new relabel analysis structure. All fields
+ * are cleared; one must fill in the details of the analysis before
+ * running it. The caller must call apol_relabel_analysis_destroy()
+ * upon the return value afterwards.
+ *
+ * @return An initialized relabel analysis structure, or NULL upon
+ * error.
+ */
+ extern apol_relabel_analysis_t *apol_relabel_analysis_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced relabel
+ * analysis, and then set it to NULL. This function does nothing if
+ * the analysis is already NULL.
+ *
+ * @param r Reference to a relabel analysis structure to destroy.
+ */
+ extern void apol_relabel_analysis_destroy(apol_relabel_analysis_t ** r);
+
+/**
+ * Set a relabel analysis to search in a specific direction. This
+ * function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Relabel analysis to set.
+ * @param dir Direction to analyze, one of the APOL_RELABEL_DIR_TO,
+ * APOL_RELABEL_DIR_FROM, APOL_RELABEL_DIR_BOTH, or
+ * APOL_RELABEL_DIR_SUBJECT.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_set_dir(const apol_policy_t * p, apol_relabel_analysis_t * r, unsigned int dir);
+
+/**
+ * Set a relabel analysis to begin searching using a given type. This
+ * function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Relabel anlysis to set.
+ * @param name Begin searching types with this non-NULL name.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_set_type(const apol_policy_t * p, apol_relabel_analysis_t * r, const char *name);
+
+/**
+ * Set a relabel analysis to return rules with this object
+ * (non-common) class. If more than one class is appended to the
+ * query, the rule's class must be one of those appended. (I.e., the
+ * rule's class must be a member of the analysis's classes.) Pass a
+ * NULL to clear all classes.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Relabel analysis to set.
+ * @param class Name of object class to add to search set, or NULL to
+ * clear all classes.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_append_class(const apol_policy_t * p, apol_relabel_analysis_t * r, const char *obj_class);
+
+/**
+ * Set a relabel analysis to return rules with this subject as their
+ * source type. If more than one subject is appended to the query,
+ * the rule's source must be one of those appended. (I.e., the rule's
+ * source must be a member of the analysis's subject.) Pass a NULL to
+ * clear all types. Note that these subjects are ignored when doing
+ * subject relabel analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Relabel analysis to set.
+ * @param subject Name of type to add to search set, or NULL to clear
+ * all subjects.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_append_subject(const apol_policy_t * p, apol_relabel_analysis_t * r, const char *subject);
+
+/**
+ * Set a relabel analysis to return only types matching a regular
+ * expression. Note that the regexp will also match types' aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Relabel anlysis to set.
+ * @param result Only return types matching this regular expression, or
+ * NULL to return all types
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_relabel_analysis_set_result_regex(const apol_policy_t * p, apol_relabel_analysis_t * r, const char *result);
+
+/******************** functions to access relabel results ********************/
+
+/**
+ * Return the relabelto vector embedded within an apol_relabel_result
+ * node. This is a vector of apol_relabel_result_pair_t objects. The
+ * caller shall not call apol_vector_destroy() upon this pointer.
+ *
+ * @param r Relabel result node.
+ *
+ * @return Pointer to a vector of rule pairs, relative to the policy
+ * originally used to generate the relabelling result.
+ */
+ extern const apol_vector_t *apol_relabel_result_get_to(const apol_relabel_result_t * r);
+
+/**
+ * Return the relabelfrom vector embedded within an
+ * apol_relabel_result node. This is a vector of
+ * apol_relabel_result_pair_t objects. The caller shall not call
+ * apol_vector_destroy() upon this pointer.
+ *
+ * @param r Relabel result node.
+ *
+ * @return Pointer to a vector of rule pairs, relative to the policy
+ * originally used to generate the relabelling result.
+ */
+ extern const apol_vector_t *apol_relabel_result_get_from(const apol_relabel_result_t * r);
+
+/**
+ * Return the relabelboth vector embedded within an
+ * apol_relabel_result node. This is a vector of
+ * apol_relabel_result_pair_t objects. The caller shall not call
+ * apol_vector_destroy() upon this pointer.
+ *
+ * @param r Relabel result node.
+ *
+ * @return Pointer to a vector of rule pairs, relative to the policy
+ * originally used to generate the relabelling result.
+ */
+ extern const apol_vector_t *apol_relabel_result_get_both(const apol_relabel_result_t * r);
+
+/**
+ * Return the resulting type for an apol_relabel_result node.
+ *
+ * @param r Relabel result node.
+ *
+ * @return Pointer to a result type.
+ */
+ extern const qpol_type_t *apol_relabel_result_get_result_type(const apol_relabel_result_t * r);
+
+/**
+ * Return the first rule from an apol_relabel_result_pair object.
+ *
+ * For object mode analysis, this is the rule that affects the
+ * starting type. Either that type or one of its attributes will be
+ * the target type for the returned rule.
+ *
+ * For subject mode analysis, this is a rule affects the starting
+ * subject. Either that subject or one of its attributes will be the
+ * source type for the returned rule.
+ *
+ * @param p Relabel result pair object.
+ *
+ * @return Rule affecting the starting type/subject.
+ */
+ extern const qpol_avrule_t *apol_relabel_result_pair_get_ruleA(const apol_relabel_result_pair_t * p);
+
+/**
+ * Return the other rule from an apol_relabel_result_pair object.
+ *
+ * For object mode analysis, this is the rule that affects the
+ * resulting type. Either that type or one of its attributes will be
+ * the target type for the returned rule.
+ *
+ * For subject mode analysis, the returned pointer will be NULL.
+ *
+ * @param p Relabel result pair object.
+ *
+ * @return Rule affecting the resulting type/subject (for object mode)
+ * or NULL (for subject mode).
+ */
+ extern const qpol_avrule_t *apol_relabel_result_pair_get_ruleB(const apol_relabel_result_pair_t * p);
+
+/**
+ * Return the intermediate type for an apol_relabel_result_pair
+ * object.
+ *
+ * For object mode analysis, this is the source type for the first
+ * rule; it also will be the source type for the other rule.
+ *
+ * For subject mode analysis, the returned pointer will be NULL.
+ *
+ * @param p Relabel result pair object.
+ *
+ * @return Intermediate type for relabel result (for object mode) or
+ * NULL (for subject mode).
+ */
+ extern const qpol_type_t *apol_relabel_result_pair_get_intermediate_type(const apol_relabel_result_pair_t * p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/render.h b/libapol/include/apol/render.h
new file mode 100644
index 0000000..0580813
--- /dev/null
+++ b/libapol/include/apol/render.h
@@ -0,0 +1,82 @@
+/**
+ * @file
+ *
+ * Public interfaces that renders things that are not already covered
+ * by one of the query files. Unless otherwise stated, all functions
+ * return a newly allocated string, which the caller is responsible
+ * for free()ing afterwards.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ * @author David Windsor dwindsor@tresys.com
+ *
+ * Copyright (C) 2003-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_RENDER_H
+#define APOL_RENDER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "mls-query.h"
+#include <qpol/policy.h>
+#include <stdlib.h>
+
+/**
+ * Given an IPv4 address (or mask) in qpol byte order, allocate and
+ * return a string representing that address.
+ *
+ * @param p Reference to a policy, for reporting errors
+ * @param addr Address (or mask) to render.
+ *
+ * @return A newly allocated string, which the caller must free.
+ * Returns NULL on error.
+ */
+ extern char *apol_ipv4_addr_render(const apol_policy_t * p, uint32_t addr[4]);
+
+/**
+ * Given an IPv6 address (or mask) in qpol byte order, allocate and
+ * return a string representing that address.
+ *
+ * @param p Reference to a policy, for reporting errors
+ * @param addr Address (or mask) to render.
+ *
+ * @return A newly allocated string, which the caller must free.
+ * Returns NULL on error.
+ */
+ extern char *apol_ipv6_addr_render(const apol_policy_t * p, uint32_t addr[4]);
+
+/**
+ * Creates a string containing the textual representation of
+ * a security context.
+ * @param p Reference to a policy.
+ * @param context Reference to the security context to be rendered.
+ *
+ * @return A newly allocated string on success, caller must free;
+ * NULL on error.
+ */
+ extern char *apol_qpol_context_render(const apol_policy_t * p, const qpol_context_t * context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/role-query.h b/libapol/include/apol/role-query.h
new file mode 100644
index 0000000..ad80490
--- /dev/null
+++ b/libapol/include/apol/role-query.h
@@ -0,0 +1,127 @@
+/**
+ * @file
+ * Public Interface for querying roles of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_ROLE_QUERY_H
+#define APOL_ROLE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_role_query apol_role_query_t;
+
+/******************** role queries ********************/
+
+/**
+ * Execute a query against all roles within the policy.
+ *
+ * @param p Policy within which to look up roles.
+ * @param r Structure containing parameters for query. If this is
+ * NULL then return all roles.
+ * @param v Reference to a vector of qpol_role_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_role_get_by_query(const apol_policy_t * p, apol_role_query_t * r, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new role query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all roles within the policy. The caller must call
+ * apol_role_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized role query structure, or NULL upon error.
+ */
+ extern apol_role_query_t *apol_role_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced role query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param r Reference to a role query structure to destroy.
+ */
+ extern void apol_role_query_destroy(apol_role_query_t ** r);
+
+/**
+ * Set a role query to return only roles that match this name. This
+ * function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role query to set.
+ * @param name Limit query to only roles with this name, or NULL to
+ * unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_query_set_role(const apol_policy_t * p, apol_role_query_t * r, const char *name);
+
+/**
+ * Set a role query to return only roles containing this type or one
+ * of its aliases. This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role query to set.
+ * @param name Limit query to only roles with this type, or NULL to
+ * unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_role_query_set_type(const apol_policy_t * p, apol_role_query_t * r, const char *name);
+
+/**
+ * Set a role query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param r Role query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_role_query_set_regex(const apol_policy_t * p, apol_role_query_t * r, int is_regex);
+
+/**
+ * See if the role passed in includes the type that is the
+ * second parameter.
+ * @param p Policy handler, to report errors.
+ * @param r Role to check if type is included in it.
+ * @param t Type that is checked against all types that are in role
+ * @return 1 if the type is included in the role, 0 if it's not, < 0 on error
+*/
+ extern int apol_role_has_type(const apol_policy_t * p, const qpol_role_t * r, const qpol_type_t * t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_ROLE_QUERY_H */
diff --git a/libapol/include/apol/terule-query.h b/libapol/include/apol/terule-query.h
new file mode 100644
index 0000000..4b1e474
--- /dev/null
+++ b/libapol/include/apol/terule-query.h
@@ -0,0 +1,321 @@
+/**
+ * @file
+ *
+ * Routines to query type enforcement rules of a policy. These are
+ * type_transition, type_member, and type_change rules.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_TERULE_QUERY_H
+#define APOL_TERULE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_terule_query apol_terule_query_t;
+
+/**
+ * Execute a query against all type enforcement rules within the policy.
+ *
+ * @param p Policy within which to look up terules.
+ * @param t Structure containing parameters for query. If this is
+ * NULL then return all terules.
+ * @param v Reference to a vector of qpol_terule_t. The vector will
+ * be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_terule_get_by_query(const apol_policy_t * p, const apol_terule_query_t * t, apol_vector_t ** v);
+
+/**
+ * Execute a query against all syntactic type enforcement rules within
+ * the policy. If the policy has line numbers, then the returned list
+ * will be sorted increasingly by line number.
+ *
+ * @param p Policy within which to look up terules. <b>Must be a
+ * source policy.</b>
+ * @param t Structure containing parameters for query. If this is
+ * NULL then return all terules.
+ * @param v Reference to a vector of qpol_syn_terule_t. The vector
+ * will be allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_syn_terule_get_by_query(const apol_policy_t * p, const apol_terule_query_t * t, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new terule query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all terules within the policy. The caller must call
+ * apol_terule_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized terule query structure, or NULL upon error.
+ */
+ extern apol_terule_query_t *apol_terule_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced terule query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param t Reference to a terule query structure to destroy.
+ */
+ extern void apol_terule_query_destroy(apol_terule_query_t ** t);
+
+/**
+ * Set a terule query to search only certain type enforcement rules
+ * within the policy. This is a bitmap; use the constants in
+ * libqpol/terule_query.h (QPOL_RULE_TYPE_TRANS, etc.) to give the
+ * rule selections.
+ *
+ * @param p Policy handler, to report errors.
+ * @param te TE rule query to set.
+ * @param rules Bitmap to indicate which rules to search, or 0 to
+ * search all rules.
+ *
+ * @return Always 0.
+ */
+ extern int apol_terule_query_set_rules(const apol_policy_t * p, apol_terule_query_t * t, unsigned int rules);
+
+/**
+ * Set a terule query to return rules whose source symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * source, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_source(const apol_policy_t * p, apol_terule_query_t * t, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set an terule query to return rules whose source symbol is matched as a type
+ * or an attribute. The symbol will match both types and attributes by default.
+ * @see apol_avrule_query_set_source() to set the symbol to match.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE
+ * and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component
+ * to match.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_source_component(const apol_policy_t * p, apol_terule_query_t * t, unsigned int component);
+
+/**
+ * Set a terule query to return rules whose target symbol matches
+ * symbol. Symbol may be a type or attribute; if it is an alias then
+ * the query will convert it to its primary prior to searching. If
+ * is_indirect is non-zero then the search will be done indirectly.
+ * If the symbol is a type, then the query matches rules with one of
+ * the type's attributes. If the symbol is an attribute, then it
+ * matches rule with any of the attribute's types.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param symbol Limit query to rules with this symbol as their
+ * target, or NULL to unset this field.
+ * @param is_indirect If non-zero, perform indirect matching.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_target(const apol_policy_t * p, apol_terule_query_t * t, const char *symbol,
+ int is_indirect);
+
+/**
+ * Set an terule query to return rules whose target symbol is matched as a type
+ * or an attribute. The symbol will match both types and attributes by default.
+ * @see apol_avrule_query_set_source() to set the symbol to match.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE
+ * and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component
+ * to match.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_target_component(const apol_policy_t * p, apol_terule_query_t * t, unsigned int component);
+
+/**
+ * Set a terule query to return rules with this default type. The
+ * symbol may be a type or any of its aliases; it may not be an
+ * attribute.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param type Name of default type to search.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_default(const apol_policy_t * p, apol_terule_query_t * t, const char *type);
+
+/**
+ * Set at terule query to return rules with this object (non-common)
+ * class. If more than one class are appended to the query, the
+ * rule's class must be one of those appended. (I.e., the rule's
+ * class must be a member of the query's classes.) Pass a NULL to
+ * clear all classes. Note that this performs straight string
+ * comparison, ignoring the regex flag.
+
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param obj_class Name of object class to add to search set.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_append_class(const apol_policy_t * p, apol_terule_query_t * t, const char *obj_class);
+
+/**
+ * Set a terule query to return rules that are in conditionals and
+ * whose conditional uses a particular boolean variable.
+ * Unconditional rules will not be returned.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param bool_name Name of boolean that conditional must contain. If
+ * NULL then search all rules.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_terule_query_set_bool(const apol_policy_t * p, apol_terule_query_t * t, const char *bool_name);
+
+/**
+ * Set a terule query to search only enabled rules within the policy.
+ * These include rules that are unconditional and those within enabled
+ * conditionals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param is_enabled Non-zero to search only enabled rules, 0 to
+ * search all rules.
+ *
+ * @return Always 0.
+ */
+ extern int apol_terule_query_set_enabled(const apol_policy_t * p, apol_terule_query_t * t, int is_enabled);
+
+/**
+ * Set a terule query to treat the source symbol as any. That is, use
+ * the same symbol for either source, target, or default of a rule.
+ * This flag does nothing if the source symbol is not set.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param is_any Non-zero to use source symbol for any field, 0 to
+ * keep source as only source.
+ *
+ * @return Always 0.
+ */
+ extern int apol_terule_query_set_source_any(const apol_policy_t * p, apol_terule_query_t * t, int is_any);
+
+/**
+ * Set a terule query to use regular expression searching for source
+ * and target types/attributes and default type. Strings will be
+ * treated as regexes instead of literals. Matching will occur against
+ * the type name or any of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t TE rule query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_terule_query_set_regex(const apol_policy_t * p, apol_terule_query_t * t, int is_regex);
+
+/**
+ * Given a single terule, return a newly allocated vector of
+ * qpol_syn_terule_t pointers (relative to the given policy) which
+ * comprise that rule. The vector will be sorted by line numbers if
+ * the policy has line numbers.
+ *
+ * @param p Policy from which to obtain syntactic rules.
+ * @param rule TE rule to convert.
+ *
+ * @return A newly allocated vector of syn_terule_t pointers. The
+ * caller is responsible for calling apol_vector_destroy() afterwards.
+ */
+ extern apol_vector_t *apol_terule_to_syn_terules(const apol_policy_t * p, const qpol_terule_t * rule);
+
+/**
+ * Given a vector of terules (qpol_terule_t pointers), return a newly
+ * allocated vector of qpol_syn_terule_t pointers (relative to the
+ * given policy) which comprise all of those rules. The returned
+ * vector will be sorted by line numbers if the policy has line
+ * numbers. Also, it will not have any duplicate syntactic rules.
+ *
+ * @param p Policy from which to obtain syntactic rules.
+ * @param rules Vector of TE rules to convert.
+ *
+ * @return A newly allocated vector of syn_terule_t pointers. The
+ * caller is responsible for calling apol_vector_destroy() afterwards.
+ */
+ extern apol_vector_t *apol_terule_list_to_syn_terules(const apol_policy_t * p, const apol_vector_t * rules);
+
+/**
+ * Render a terule to a string.
+ *
+ * @param policy Policy handler, to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+ */
+ extern char *apol_terule_render(const apol_policy_t * policy, const qpol_terule_t * rule);
+
+/**
+ * Render a syntactic terule to a string.
+ *
+ * @param policy Policy handler to report errors.
+ * @param rule The rule to render.
+ *
+ * @return a newly malloc()'d string representation of the rule, or NULL on
+ * failure; if the call fails, errno will be set. The caller is responsible
+ * for calling free() on the returned string.
+*/
+ extern char *apol_syn_terule_render(const apol_policy_t * policy, const qpol_syn_terule_t * rule);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/type-query.h b/libapol/include/apol/type-query.h
new file mode 100644
index 0000000..a571b19
--- /dev/null
+++ b/libapol/include/apol/type-query.h
@@ -0,0 +1,172 @@
+/**
+ * @file
+ *
+ * Routines to query types and attributes of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_TYPE_QUERY_H
+#define APOL_TYPE_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_type_query apol_type_query_t;
+ typedef struct apol_attr_query apol_attr_query_t;
+
+/******************** type queries ********************/
+
+/**
+ * Execute a query against all types within the policy. The results
+ * will only contain types, not aliases nor attributes.
+ *
+ * @param p Policy within which to look up types.
+ * @param t Structure containing parameters for query. If this is
+ * NULL then return all types.
+ * @param v Reference to a vector of qpol_type_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_type_get_by_query(const apol_policy_t * p, apol_type_query_t * t, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new type query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all types within the policy. The caller must call
+ * apol_type_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized type query structure, or NULL upon error.
+ */
+ extern apol_type_query_t *apol_type_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced type query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param t Reference to a type query structure to destroy.
+ */
+ extern void apol_type_query_destroy(apol_type_query_t ** t);
+
+/**
+ * Set a type query to return only types that match this name. The
+ * name may be either a type or one of its aliases. This function
+ * duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Type query to set.
+ * @param name Limit query to only types or aliases with this name, or
+ * NULL to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_type_query_set_type(const apol_policy_t * p, apol_type_query_t * t, const char *name);
+
+/**
+ * Set a type query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ * Matching will occur against the type name or any of its aliases.
+ *
+ * @param p Policy handler, to report errors.
+ * @param t Type query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_type_query_set_regex(const apol_policy_t * p, apol_type_query_t * t, int is_regex);
+
+/******************** attribute queries ********************/
+
+/**
+ * Execute a query against all attributes within the policy. The
+ * results will only contain attributes, not types nor aliases.
+ *
+ * @param p Policy within which to look up attributes.
+ * @param a Structure containing parameters for query. If this is
+ * NULL then return all attributes.
+ * @param v Reference to a vector of qpol_type_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_attr_get_by_query(const apol_policy_t * p, apol_attr_query_t * a, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new attribute query structure. All fields
+ * are initialized, such that running this blank query results in
+ * returning all attributes within the policy. The caller must call
+ * apol_attr_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized attribute query structure, or NULL upon error.
+ */
+ extern apol_attr_query_t *apol_attr_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced attribute
+ * query, and then set it to NULL. This function does nothing if the
+ * query is already NULL.
+ *
+ * @param a Reference to an attribute query structure to destroy.
+ */
+ extern void apol_attr_query_destroy(apol_attr_query_t ** a);
+
+/**
+ * Set an attribute query to return only attributes that match this
+ * name. This function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a Attribute query to set.
+ * @param name Limit query to only attributes with this name, or NULL
+ * to unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_attr_query_set_attr(const apol_policy_t * p, apol_attr_query_t * a, const char *name);
+
+/**
+ * Set an attribute query to use regular expression searching for all
+ * of its fields. Strings will be treated as regexes instead of
+ * literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param a Attribute query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_attr_query_set_regex(const apol_policy_t * p, apol_attr_query_t * a, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/types-relation-analysis.h b/libapol/include/apol/types-relation-analysis.h
new file mode 100644
index 0000000..1278072
--- /dev/null
+++ b/libapol/include/apol/types-relation-analysis.h
@@ -0,0 +1,380 @@
+/**
+ * @file
+ *
+ * Routines to perform a two-types relationship analysis.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2003-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_TYPES_RELATION_ANALYSIS_H
+#define APOL_TYPES_RELATION_ANALYSIS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include <qpol/policy.h>
+
+/* Specify a which types relationship analysis/analyses to run using
+ * these bit values.
+ */
+#define APOL_TYPES_RELATION_COMMON_ATTRIBS 0x0001
+#define APOL_TYPES_RELATION_COMMON_ROLES 0x0002
+#define APOL_TYPES_RELATION_COMMON_USERS 0x0004
+#define APOL_TYPES_RELATION_SIMILAR_ACCESS 0x0010
+#define APOL_TYPES_RELATION_DISSIMILAR_ACCESS 0x0020
+#define APOL_TYPES_RELATION_ALLOW_RULES 0x0100
+#define APOL_TYPES_RELATION_TYPE_RULES 0x0200
+#define APOL_TYPES_RELATION_DOMAIN_TRANS_AB 0x0400
+#define APOL_TYPES_RELATION_DOMAIN_TRANS_BA 0x0800
+#define APOL_TYPES_RELATION_DIRECT_FLOW 0x1000
+#define APOL_TYPES_RELATION_TRANS_FLOW_AB 0x4000
+#define APOL_TYPES_RELATION_TRANS_FLOW_BA 0x8000
+
+ typedef struct apol_types_relation_analysis apol_types_relation_analysis_t;
+ typedef struct apol_types_relation_result apol_types_relation_result_t;
+ typedef struct apol_types_relation_access apol_types_relation_access_t;
+
+/********** functions to do types relation analysis **********/
+
+/**
+ * Execute a two types relationship analysis against a particular
+ * policy.
+ *
+ * @param p Policy within which to look up relationships.
+ * @param tr A non-NULL structure containing parameters for analysis.
+ * @param r Reference to a apol_types_relation_result_t. The object
+ * will be allocated by this function. The caller must call
+ * apol_types_relation_result_destroy() afterwards. This will be set
+ * to NULL upon no results or upon error.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_types_relation_analysis_do(apol_policy_t * p,
+ const apol_types_relation_analysis_t * tr, apol_types_relation_result_t ** r);
+
+/**
+ * Allocate and return a new two types relationship analysis
+ * structure. All fields are cleared; one must fill in the details of
+ * the analysis before running it. The caller must call
+ * apol_types_relation_analysis_destroy() upon the return value
+ * afterwards.
+ *
+ * @return An initialized two types relationship analysis structure, or
+ * NULL upon error.
+ */
+ extern apol_types_relation_analysis_t *apol_types_relation_analysis_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced types relation
+ * analysis, and then set it to NULL. This function does nothing if
+ * the analysis is already NULL.
+ *
+ * @param tr Reference to a types relation analysis structure to
+ * destroy.
+ */
+ extern void apol_types_relation_analysis_destroy(apol_types_relation_analysis_t ** tr);
+
+/**
+ * Set a types relation analysis to begin analysis from this first
+ * type. This function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param tr Types relation analysis to set.
+ * @param name Perform analysis with this non-NULL name.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_types_relation_analysis_set_first_type(const apol_policy_t * p, apol_types_relation_analysis_t * tr,
+ const char *name);
+
+/**
+ * Set a types relation analysis to begin analysis from this other
+ * type. This function must be called prior to running the analysis.
+ *
+ * @param p Policy handler, to report errors.
+ * @param tr Types relation analysis to set.
+ * @param name Perform analysis with this other non-NULL name.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_types_relation_analysis_set_other_type(const apol_policy_t * p, apol_types_relation_analysis_t * tr,
+ const char *name);
+
+/**
+ * Set a types relation analysis to run the specified
+ * analysis/analyses. This is a bitmap; use the defines
+ * APOL_TYPES_RELATION_COMMON_ATTRIBUTES etc. to specify which one(s)
+ * to run.
+ *
+ * @param p Policy handler, to report errors.
+ * @param tr Types relation analysis to set.
+ * @param analyses Bitmap to indicate which analyses to run, or 0 to
+ * run them all.
+ *
+ * @return Always 0.
+ */
+ extern int apol_types_relation_analysis_set_analyses(const apol_policy_t * p, apol_types_relation_analysis_t * tr,
+ unsigned int analyses);
+
+/*************** functions to access types relation results ***************/
+
+/**
+ * Deallocate all memory associated with a types relation analysis
+ * result, including the pointer itself. This function does nothing
+ * if the result is already NULL.
+ *
+ * @param result Reference to a types relation result structure to
+ * destroy.
+ */
+ extern void apol_types_relation_result_destroy(apol_types_relation_result_t ** result);
+
+/**
+ * Return the vector of attributes common to the two types. This is a
+ * vector of qpol_type_t pointers. The caller <b>should not</b> call
+ * apol_vector_destroy() upon the returned vector. If the user did
+ * not request this analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get common
+ * attributes.
+ *
+ * @return Vector of common attributes, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_attributes(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of roles common to the two types. This is a
+ * vector of qpol_role_t pointers. The caller <b>should not</b> call
+ * apol_vector_destroy() upon the returned vector. If the user did
+ * not request this analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get common roles.
+ *
+ * @return Vector of common roles, or NULL if analysis was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_roles(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of users common to the two types. This is a
+ * vector of qpol_user_t pointers. The caller <b>should not</b> call
+ * apol_vector_destroy() upon the returned vector. If the user did
+ * not request this analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get common users.
+ *
+ * @return Vector of common users, or NULL if analysis was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_users(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of accesses similar to the two types. This is a
+ * vector of apol_types_relation_access_t pointers. The vector will
+ * contain only the rules that the first type had. Call
+ * apol_types_relation_result_get_similar_other() to get the
+ * complementary vector (i.e., both vectors will have the same types).
+ * The caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get similar accesses.
+ *
+ * @return Vector of similar accesses, or NULL if analysis was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_similar_first(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of accesses similar to the two types. This is a
+ * vector of apol_types_relation_access_t pointers. The vector will
+ * contain only the rules that the other type had. Call
+ * apol_types_relation_result_get_similar_first() to get the
+ * complementary vector (i.e., both vectors will have the same types).
+ * The caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get similar accesses.
+ *
+ * @return Vector of similar accesses, or NULL if analysis was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_similar_other(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of accesses dissimilar for the first type (i.e.,
+ * types that the first type reaches that the other type does not).
+ * This is a vector of apol_types_relation_access_t pointers. The
+ * caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get dissimilar
+ * accesses.
+ *
+ * @return Vector of dissimilar accesses, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_dissimilar_first(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of accesses dissimilar for the other type (i.e.,
+ * types that the other type reaches that the first type does not).
+ * This is a vector of apol_types_relation_access_t pointers. The
+ * caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get dissimilar
+ * accesses.
+ *
+ * @return Vector of dissimilar accesses, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_dissimilar_other(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of allow rules involving both types (allow one
+ * type to the other). This is a vector of qpol_avrule_t pointers.
+ * The caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get rules.
+ *
+ * @return Vector of allow rules, or NULL if analysis was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_allowrules(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of type transition / type change rules involving
+ * both types. This is a vector of qpol_terule_t pointers. The
+ * caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get rules.
+ *
+ * @return Vector of type enforcement rules, or NULL if analysis was
+ * not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_typerules(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of apol_infoflow_result_t pointers corresponding
+ * to a direct information flow analysis between both types. The
+ * caller <b>should not</b> call apol_vector_destroy() upon the
+ * returned vector. If the user did not request this analysis then
+ * the return value will be NULL.
+ *
+ * @param result Types relation result from which to get information
+ * flows.
+ *
+ * @return Vector of infoflow results, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_directflows(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of apol_infoflow_result_t pointers corresponding
+ * to a transitive information flow analysis between the first type to
+ * the other. The caller <b>should not</b> call apol_vector_destroy()
+ * upon the returned vector. If the user did not request this
+ * analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get information
+ * flows.
+ *
+ * @return Vector of infoflow results, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_transflowsAB(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of apol_infoflow_result_t pointers corresponding
+ * to a transitive information flow analysis between the other type to
+ * the first. The caller <b>should not</b> call apol_vector_destroy()
+ * upon the returned vector. If the user did not request this
+ * analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get information
+ * flows.
+ *
+ * @return Vector of infoflow results, or NULL if analysis was not
+ * run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_transflowsBA(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of apol_domain_trans_result_t pointers
+ * corresponding to a domain transition analysis between the first
+ * type to the other. The caller <b>should not</b> call
+ * apol_vector_destroy() upon the returned vector. If the user did
+ * not request this analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get domain
+ * transitions.
+ *
+ * @return Vector of domain transition results, or NULL if analysis
+ * was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_domainsAB(const apol_types_relation_result_t * result);
+
+/**
+ * Return the vector of apol_domain_trans_result_t pointers
+ * corresponding to a domain transition analysis between the other
+ * type to the first. The caller <b>should not</b> call
+ * apol_vector_destroy() upon the returned vector. If the user did
+ * not request this analysis then the return value will be NULL.
+ *
+ * @param result Types relation result from which to get domain
+ * transitions.
+ *
+ * @return Vector of domain transition results, or NULL if analysis
+ * was not run.
+ */
+ extern const apol_vector_t *apol_types_relation_result_get_domainsBA(const apol_types_relation_result_t * result);
+
+/**
+ * Given a types relation access node, return the type stored within.
+ *
+ * @param a Types relation access node.
+ *
+ * @return Pointer to the type stored within.
+ */
+ extern const qpol_type_t *apol_types_relation_access_get_type(const apol_types_relation_access_t * a);
+
+/**
+ * Given a types relation access node, return the vector of
+ * qpol_avrule_t pointers stored within.
+ *
+ * @param a Types relation access node.
+ *
+ * @return Pointer to the vector of rules. The caller <b>must not</b>
+ * destroy this vector.
+ */
+ extern const apol_vector_t *apol_types_relation_access_get_rules(const apol_types_relation_access_t * a);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/user-query.h b/libapol/include/apol/user-query.h
new file mode 100644
index 0000000..9038bf4
--- /dev/null
+++ b/libapol/include/apol/user-query.h
@@ -0,0 +1,150 @@
+/**
+ * @file
+ * Public Interface for querying users of a policy.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_USER_QUERY_H
+#define APOL_USER_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "policy.h"
+#include "vector.h"
+#include "mls-query.h"
+#include <qpol/policy.h>
+
+ typedef struct apol_user_query apol_user_query_t;
+
+/******************** user queries ********************/
+
+/**
+ * Execute a query against all users within the policy.
+ *
+ * @param p Policy within which to look up users.
+ * @param u Structure containing parameters for query. If this is
+ * NULL then return all users.
+ * @param v Reference to a vector of qpol_user_t. The vector will be
+ * allocated by this function. The caller must call
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
+ * results or upon error.
+ *
+ * @return 0 on success (including none found), negative on error.
+ */
+ extern int apol_user_get_by_query(const apol_policy_t * p, apol_user_query_t * u, apol_vector_t ** v);
+
+/**
+ * Allocate and return a new user query structure. All fields are
+ * initialized, such that running this blank query results in
+ * returning all users within the policy. The caller must call
+ * apol_user_query_destroy() upon the return value afterwards.
+ *
+ * @return An initialized user query structure, or NULL upon error.
+ */
+ extern apol_user_query_t *apol_user_query_create(void);
+
+/**
+ * Deallocate all memory associated with the referenced user query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ *
+ * @param u Reference to a user query structure to destroy.
+ */
+ extern void apol_user_query_destroy(apol_user_query_t ** u);
+
+/**
+ * Set a user query to return only users that match this name. This
+ * function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param u User query to set.
+ * @param name Limit query to only users this name, or NULL to unset
+ * this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_user_query_set_user(const apol_policy_t * p, apol_user_query_t * u, const char *name);
+
+/**
+ * Set a user query to return only users containing this role. This
+ * function duplicates the incoming name.
+ *
+ * @param p Policy handler, to report errors.
+ * @param u User query to set.
+ * @param role Limit query to only users with this role, or NULL to
+ * unset this field.
+ *
+ * @return 0 on success, negative on error.
+ */
+ extern int apol_user_query_set_role(const apol_policy_t * p, apol_user_query_t * u, const char *role);
+
+/**
+ * Set a user query to return only users containing this default
+ * level. This function takes ownership of the level, such that the
+ * caller must not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param u User query to which set.
+ * @param level Limit query to only users with this level as their
+ * default, or NULL to unset this field.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_user_query_set_default_level(const apol_policy_t * p, apol_user_query_t * u, apol_mls_level_t * level);
+
+/**
+ * Set a user query to return only users matching a MLS range. This
+ * function takes ownership of the range, such that the caller must
+ * not modify nor destroy it afterwards.
+ *
+ * @param p Policy handler, to report errors.
+ * @param u User query to set.
+ * @param range Limit query to only users matching this range, or NULL
+ * to unset this field.
+ * @param range_match Specifies how to match a user to a range. This
+ * must be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. This parameter is ignored if range is NULL.
+ *
+ * @return Always returns 0.
+ */
+ extern int apol_user_query_set_range(const apol_policy_t * p, apol_user_query_t * u, apol_mls_range_t * range,
+ unsigned int range_match);
+
+/**
+ * Set a user query to use regular expression searching for all of its
+ * fields. Strings will be treated as regexes instead of literals.
+ *
+ * @param p Policy handler, to report errors.
+ * @param u User query to set.
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
+ *
+ * @return Always 0.
+ */
+ extern int apol_user_query_set_regex(const apol_policy_t * p, apol_user_query_t * u, int is_regex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_USER_QUERY_H */
diff --git a/libapol/include/apol/util.h b/libapol/include/apol/util.h
new file mode 100644
index 0000000..99db168
--- /dev/null
+++ b/libapol/include/apol/util.h
@@ -0,0 +1,336 @@
+/**
+ * @file
+ *
+ * Miscellaneous, uncategorized functions for libapol.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2001-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_UTIL_H
+#define APOL_UTIL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "vector.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * Return an immutable string describing this library's version.
+ *
+ * @return String describing this library.
+ */
+ extern const char *libapol_get_version(void);
+
+/**
+ * Given a portcon protocol, return a read-only string that describes
+ * that protocol.
+ *
+ * @param protocol Portcon protocol, one of IPPROTO_TCP or IPPROTO_UDP
+ * from netinet/in.h.
+ *
+ * @return A string that describes the protocol, or NULL if the
+ * protocol is invalid. <b>Do not free() this string.</b>
+ */
+ extern const char *apol_protocol_to_str(uint8_t protocol);
+
+/**
+ * Given the name of a portcon protocol, return its numeric value.
+ *
+ * @param protocol_str Portcon protocol, one of "tcp", "TCP", "udp", or "UDP".
+ *
+ * @return Numeric value for the protocol, one of IPPROTO_TCP or IPPROTO_UDP
+ * from netinet/in.h. Upon error return 0.
+ */
+ extern uint8_t apol_str_to_protocol(const char *protocol_str);
+
+/**
+ * Given a string representing and IP value (mask or address, IPv4 or
+ * IPv6), write to an array that value in the same bit order that
+ * qpol uses. If the IP was in IPv4 format, only write to the first
+ * element and zero the remainder.
+ *
+ * @param str A string representing and IP value, either in IPv4 or
+ * IPv6 format.
+ * @param ip Array to which write converted value.
+ *
+ * @return QPOL_IPV4 if the string is in IPv4 format, QPOL_IPV6 if
+ * in IPv6, < 0 on error.
+ */
+ extern int apol_str_to_internal_ip(const char *str, uint32_t ip[4]);
+
+/**
+ * Given a genfscon object class, return a read-only string that
+ * describes that class.
+ *
+ * @param objclass Object class, one of QPOL_CLASS_BLK_FILE,
+ * QPOL_CLASS_CHR_FILE, etc.
+ *
+ * @return A string that describes the object class, or NULL if the
+ * object class is invalid. <b>Do not free() this string.</b>
+ *
+ * @see <qpol/genfscon_query.h> for a list of valid object classes.
+ */
+ extern const char *apol_objclass_to_str(uint32_t objclass);
+
+/**
+ * Given a string representing a genfscon object class, return its
+ * numeric identifier. Valid strings may be obtained by calling
+ * apol_objclass_to_str().
+ *
+ * @param objclass Object class, one of "any", "file", etc.
+ *
+ * @return Numeric identifier for object class, or 0 if unknown.
+ *
+ * @see <qpol/genfscon_query.h> for a list of valid object classes.
+ */
+ extern uint32_t apol_str_to_objclass(const char *objclass);
+
+/**
+ * Given a fs_use behavior type, return a read-only string that
+ * describes that fs_use behavior.
+ *
+ * @param behavior A fs_use behavior, one of QPOL_FS_USE_PSID,
+ * QPOL_FS_USE_XATTR, etc.
+ *
+ * @return A string that describes the behavior, or NULL if the
+ * behavior is invalid. <b>Do not free() this string.</b>
+ */
+ extern const char *apol_fs_use_behavior_to_str(uint32_t behavior);
+
+/**
+ * Given a fs_use behavior string, return its numeric value.
+ *
+ * @param behavior A fs_use behavior, one of "fs_use_psid",
+ * "fs_use_xattr", etc.
+ *
+ * @return A numeric representation for the behavior, one of
+ * QPOL_FS_USE_PSID, QPOL_FS_USE_XATTR, etc, or < 0 if the string is
+ * invalid.
+ */
+ extern int apol_str_to_fs_use_behavior(const char *behavior);
+
+/**
+ * Given a rule type, return a read-only string that describes that
+ * rule.
+ *
+ * @param rule_type A policy rule type, one of QPOL_RULE_ALLOW,
+ * QPOL_RULE_TYPE_CHANGE, etc.
+ *
+ * @return A string that describes the rule, or NULL if the rule_type
+ * is invalid. <b>Do not free() this string.</b>
+ */
+ extern const char *apol_rule_type_to_str(uint32_t rule_type);
+
+/**
+ * Given a conditional expression type, return a read-only string that
+ * describes that operator.
+ *
+ * @param expr_type An expression type, one of QPOL_COND_EXPR_BOOL,
+ * QPOL_COND_EXPR_NOT, etc.
+ *
+ * @return A string that describes the expression, or NULL if the
+ * expr_type is invalid. <b>Do not free() this string.</b>
+ */
+ extern const char *apol_cond_expr_type_to_str(uint32_t expr_type);
+
+/**
+ * Given a file name, search and return that file's path on the
+ * running system. First search the present working directory, then
+ * the directory at APOL_INSTALL_DIR (an environment variable), then
+ * apol's install dir.
+ *
+ * @param file_name File to find.
+ *
+ * @return File's path, or NULL if not found. Caller must free() this
+ * string afterwards.
+ */
+ extern char *apol_file_find(const char *file_name);
+
+/**
+ * Given a file name, search and return that file's full path
+ * (directory + file name) on the running system. First search the
+ * present working directory, then the directory at APOL_INSTALL_DIR
+ * (an environment variable), then apol's install dir.
+ *
+ * @param file_name File to find.
+ *
+ * @return File's path + file name, or NULL if not found. Caller must
+ * free() this string afterwards.
+ */
+ extern char *apol_file_find_path(const char *file_name);
+
+/**
+ * Given a file name for a user configuration, search and return that
+ * file's path + file name in the user's home directory.
+ *
+ * @param file_name File to find.
+ *
+ * @return File's path + file name, or NULL if not found. Caller must
+ * free() this string afterwards.
+ */
+ extern char *apol_file_find_user_config(const char *file_name);
+
+/**
+ * Given a file name, read the file's contents into a newly allocated
+ * buffer. The caller must free() this buffer afterwards.
+ *
+ * @param fname Name of file to read.
+ * @param buf Reference to a newly allocated buffer.
+ * @param len Reference to the number of bytes read.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+ extern int apol_file_read_to_buffer(const char *fname, char **buf, size_t * len);
+/**
+ * Given a file pointer into a config file, read and return the value
+ * for the given config var. The caller must free() the returned
+ * string afterwards.
+ *
+ * @param var Name of configuration variable to obtain.
+ * @param fp An open file pointer into a configuration file. This
+ * function will not maintain the pointer's current location.
+ *
+ * @return A newly allocated string containing the variable's value,
+ * or NULL if not found or error.
+ */
+ extern char *apol_config_get_var(const char *var, FILE * fp);
+
+/**
+ * Given a string of tokens, allocate and return a vector of strings
+ * initialized to those tokens.
+ *
+ * @param s String to split.
+ * @param delim Delimiter for tokens, as per strsep(3).
+ *
+ * @return A newly allocated vector of strings containing the
+ * variable's values, or NULL if not found or error. Note that the
+ * vector could be empty if the config var does not exist or has an
+ * empty value. The caller must call apol_vector_destroy()
+ * afterwards.
+ */
+ extern apol_vector_t *apol_str_split(const char *s, const char *delim);
+
+/**
+ * Given a vector of strings, allocate and return a string that joins
+ * the vector using the given separator. The caller is responsible
+ * for free()ing the string afterwards.
+ *
+ * @param list Vector of strings to join.
+ * @param delim Delimiter character(s) for the concatenated string.
+ *
+ * @return An allocated concatenated string, or NULL upon error. If
+ * the list is empty then return an empty string. The caller is
+ * responsible for calling free() upon the return value.
+ */
+ extern char *apol_str_join(const apol_vector_t * list, const char *delim);
+
+/**
+ * Given a mutable string, modify the string by removing both starting
+ * and trailing whitespace characters.
+ *
+ * @param str String to modify.
+ */
+ extern void apol_str_trim(char *str);
+
+/**
+ * Append a string to an existing dynamic mutable string, expanding
+ * the target string if necessary. The caller must free() the target
+ * string. If tgt is NULL then initially allocate the resulting
+ * string.
+ *
+ * @param tgt Reference to a string to modify, or NULL to create a new
+ * string.
+ * @param tgt_sz Pointer to number of bytes currently allocated to
+ * tgt. This will be updated with the new string size. If *tgt is
+ * NULL then this existing value is ignored. (It will still be updated
+ * afterwards).
+ * @param str String to append.
+ *
+ * @return 0 on success. On error, return < 0 and set errno; tgt will be
+ * free()d and set to NULL, tgt_sz will be set to 0.
+ */
+ extern int apol_str_append(char **tgt, size_t * tgt_sz, const char *str);
+
+/**
+ * Append a string to an existing dynamic mutable string, expanding
+ * the target string if necessary. The string to append is computed
+ * using the format string, as per printf(3). The caller must free()
+ * the target string. If tgt is NULL then initially allocate the
+ * resulting string.
+ *
+ * @param tgt Reference to a string to modify, or NULL to create a new
+ * string.
+ * @param tgt_sz Pointer to number of bytes currently allocated to
+ * tgt. This will be updated with the new string size. If *tgt is
+ * NULL then the existing value is ignored. (It will still be updated
+ * afterwards).
+ * @param fmt Format for the string with which append, as per
+ * printf(3).
+ *
+ * @return 0 on success. On error, return < 0 and set errno; tgt will be
+ * free()d and set to NULL, tgt_sz will be set to 0.
+ */
+ extern int apol_str_appendf(char **tgt, size_t * tgt_sz, const char *fmt, ...);
+
+/* declaration duplicated below to satisfy doxygen */
+ extern int apol_str_appendf(char **tgt, size_t * tgt_sz, const char *fmt, ...) __attribute__ ((format(printf, 3, 4)));
+
+/**
+ * Test whether a given string is only white space.
+ *
+ * @param str String to test.
+ * @return 1 if string is either NULL or only whitespace, 0 otherwise.
+ */
+ extern int apol_str_is_only_white_space(const char *str);
+
+/**
+ * Wrapper around strcmp for use in vector and BST comparison functions.
+ *
+ * @param a String to compare.
+ * @param b The other string to compare.
+ * @param unused Not used. (exists to match expected function signature)
+ *
+ * @return Less than, equal to, or greater than 0 if string a is found
+ * to be less than, identical to, or greater than string b
+ * respectively.
+ */
+ extern int apol_str_strcmp(const void *a, const void *b, void *unused __attribute__ ((unused)));
+
+/**
+ * Wrapper around strdup for use in vector and BST cloning functions.
+ *
+ * @param elem String to duplicate.
+ * @param unused Not used. (exists to match expected function signature)
+ *
+ * @return A new string that is a duplicate of elem, or NULL upon error.
+ */
+ extern void *apol_str_strdup(const void *elem, void *unused __attribute__ ((unused)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libapol/include/apol/vector.h b/libapol/include/apol/vector.h
new file mode 100644
index 0000000..f690bf0
--- /dev/null
+++ b/libapol/include/apol/vector.h
@@ -0,0 +1,335 @@
+/**
+ * @file
+ * Contains the API for a generic vector. Note that vector functions
+ * are not thread-safe.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef APOL_VECTOR_H
+#define APOL_VECTOR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <qpol/iterator.h>
+
+ typedef struct apol_vector apol_vector_t;
+
+ typedef int (apol_vector_comp_func) (const void *a, const void *b, void *data);
+ typedef void (apol_vector_free_func) (void *elem);
+ typedef void *(apol_vector_dup_func) (const void *elem, void *data);
+
+/**
+ * Allocate and initialize an empty vector with default
+ * capacity.
+ *
+ * @param fr Function to call when destroying the vector. Each
+ * element of the vector will be passed into this function; it should
+ * free the memory used by that element. If this parameter is NULL,
+ * the elements will not be freed.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used.
+ */
+ extern apol_vector_t *apol_vector_create(apol_vector_free_func * fr);
+
+/**
+ * Allocate and initialize an empty vector with starting capacity of
+ * cap.
+ *
+ * @param cap The starting capacity to allocate for the internal
+ * array.
+ * @param fr Function to call when destroying the vector. Each
+ * element of the vector will be passed into this function; it should
+ * free the memory used by that element. If this parameter is NULL,
+ * the elements will not be freed.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used.
+ */
+ extern apol_vector_t *apol_vector_create_with_capacity(size_t cap, apol_vector_free_func * fr);
+
+/**
+ * Allocate and return a vector that has been initialized with the
+ * contents of a qpol iterator. <b>This function merely makes a
+ * shallow copy of the iterator's contents</b>; any memory ownership
+ * restrictions imposed by the iterator apply to this vector as well.
+ * Also note that this function begins copying from the iterator's
+ * current position, leaving the iterator at its end position
+ * afterwards.
+ *
+ * @param iter qpol iterator from which to obtain vector's contents.
+ * @param fr Function to call when destroying the vector. Each
+ * element of the vector will be passed into this function; it should
+ * free the memory used by that element. If this parameter is NULL,
+ * the elements will not be freed.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used.
+ */
+ extern apol_vector_t *apol_vector_create_from_iter(qpol_iterator_t * iter, apol_vector_free_func * fr);
+
+/**
+ * Allocate and return a vector that has been initialized with the
+ * contents of another vector.
+ *
+ * @param v Vector from which to copy.
+ * @param dup If NULL, then make a shallow copy of the original
+ * vector's contents. Otherwise this function will be called upon
+ * for each element from the original vector; the return value will
+ * be the value stored in the new vector.
+ * @param data Arbitrary data to pass as dup's second parameter.
+ * @param fr Function to call when destroying the new vector. Each
+ * element of the vector will be passed into this function; it should
+ * free the memory used by that element. If this parameter is NULL,
+ * the elements will not be freed.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used.
+ */
+ extern apol_vector_t *apol_vector_create_from_vector(const apol_vector_t * v, apol_vector_dup_func * dup, void *data,
+ apol_vector_free_func * fr);
+
+/**
+ * Allocate and return a vector that has been initialized with the
+ * contents common to two other vectors. <b>This function merely
+ * makes a shallow copy of the vectors' contents</b>; any memory
+ * ownership restrictions imposed by the original vectors apply to
+ * this new vector as well. Note that if a source vector contains
+ * duplicate elements the returned vector may (or may not) have
+ * duplicates as well. If the caller does not want duplicate entries
+ * then apol_vector_sort_uniquify() should be called afterwards.
+ *
+ * @param v1 First vector from which to compute the intersection.
+ * @param v2 Other vector to compute intersection.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The expected return value from this function is
+ * less than, equal to, or greater than 0 if the first argument is
+ * less than, equal to, or greater than the second respectively. If
+ * this is NULL then do pointer address comparison.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ *
+ * @return A pointer to a newly created vector on success and NULL on
+ * failure. If the call fails, errno will be set. The caller is
+ * responsible for calling apol_vector_destroy() to free memory used.
+ */
+ extern apol_vector_t *apol_vector_create_from_intersection(const apol_vector_t * v1,
+ const apol_vector_t * v2, apol_vector_comp_func * cmp,
+ void *data);
+
+/**
+ * Free a vector and any memory used by it. This will recursively
+ * invoke the free function that was stored within the vector when it
+ * was created.
+ *
+ * @param v Pointer to the vector to free. The pointer will be set
+ * to NULL afterwards. If already NULL then this function does
+ * nothing.
+ */
+ extern void apol_vector_destroy(apol_vector_t ** v);
+
+/**
+ * Get the number of elements in the vector.
+ *
+ * @param v The vector from which to get the number of elements.
+ * Must be non-NULL.
+ *
+ * @return The number of elements in the vector; if v is NULL,
+ * returns 0.
+ */
+ extern size_t apol_vector_get_size(const apol_vector_t * v);
+
+/**
+ * Get the current capacity of the vector.
+ *
+ * @param v The vector from which to get the current capacity. Must
+ * be non-NULL.
+ *
+ * @return The capacity of the vector; this value will be greater or
+ * equal to the number of elements in the vector. If v is NULL,
+ * returns 0.
+ */
+ extern size_t apol_vector_get_capacity(const apol_vector_t * v);
+
+/**
+ * Get the element at the requested index.
+ *
+ * @param v The vector from which to get the element.
+ * @param idx The index of the desired element.
+ *
+ * @return A pointer to the element requested. If v is NULL or idx is
+ * out of range, returns NULL and sets errno.
+ */
+ extern void *apol_vector_get_element(const apol_vector_t * v, size_t idx);
+
+/**
+ * Find an element within a vector, returning its index within the vector.
+ *
+ * @param v The vector from which to get the element.
+ * @param elem The element to find.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The first parameter will be an existing element
+ * from the vector; next will be elem and then data. The expected
+ * return value from this function is less than, equal to, or greater
+ * than 0 if the first argument is less than, equal to, or greater
+ * than the second respectively. For use in this function the return
+ * value is only checked for 0 or non-zero return. If this is NULL
+ * then do pointer address comparison.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ * @param i Index into vector where element was found. This value is
+ * undefined if the element was not found.
+ *
+ * @return 0 if element was found, or < 0 if not found.
+ */
+ extern int apol_vector_get_index(const apol_vector_t * v, const void *elem, apol_vector_comp_func * cmp, void *data,
+ size_t * i);
+
+/**
+ * Add an element to the end of a vector.
+ *
+ * @param v The vector to which to add the element.
+ * @param elem The element to add. Once added the element will be
+ * the last element in the vector.
+ *
+ * @return 0 on success and < 0 on failure. If the call fails, errno
+ * will be set and v will be unchanged.
+ */
+ extern int apol_vector_append(apol_vector_t * v, void *elem);
+
+/**
+ * Add an element to the end of a vector unless that element is equal
+ * to an existing element.
+ *
+ * @param v The vector to which to add the element.
+ * @param elem The element to add; must be non-NULL.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The expected return value from this function is
+ * less than, equal to, or greater than 0 if the first argument is
+ * less than, equal to, or greater than the second respectively. For
+ * use in this function the return value is only checked for 0 or
+ * non-zero return. If this is NULL then do pointer address
+ * comparison.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ *
+ * @return 0 on success, < 0 on failure, and > 0 if the element
+ * already exists in the vector. If the call fails or the element
+ * already exists errno will be set.
+ */
+ extern int apol_vector_append_unique(apol_vector_t * v, void *elem, apol_vector_comp_func * cmp, void *data);
+
+/**
+ * Concatenate two vectors. Appends all elements of src to dest.
+ * <b>NOTE: No type checking is done for elements in the two
+ * vectors.</b> Elements are not deep copies.
+ * @param dest Vector to which to append elements.
+ * @param src Vector containing elements to append.
+ * @return 0 on success and < 0 on failure; if the call fails,
+ * errno will be set and dest's contents will be reverted.
+ */
+ extern int apol_vector_cat(apol_vector_t * dest, const apol_vector_t * src);
+
+/**
+ * Remove an element from a vector, and renumber all subsequent
+ * elements. <b>This does not free memory that was used by the
+ * removed element</b>; the caller is responsible for doing that.
+ *
+ * @param v Vector containing element.
+ * @param idx Index to the element to remove.
+ * @return 0 on success and < 0 on failure; if the call fails,
+ * errno will be set and v's contents will be reverted.
+ */
+ extern int apol_vector_remove(apol_vector_t * v, const size_t idx);
+
+/**
+ * Compare two vectors, determining if one is different than the
+ * other. This uses a callback to compare elements across the
+ * vectors.
+ *
+ * @param a First vector to compare.
+ * @param b Second vector to compare.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The expected return value from this function is
+ * less than, equal to, or greater than 0 if the first argument is
+ * less than, equal to, or greater than the second respectively. If
+ * this is NULL then do pointer address comparison.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ * @param i Reference to where to store the index of the first
+ * detected difference. The value is undefined if vectors are
+ * equivalent (return value of 0). Note that the index may be
+ * greater than a vector's size if the vectors are of unequal
+ * lengths.
+ *
+ * @return < 0 if vector A is less than B, > 0 if A is greater than
+ * B, or 0 if equivalent.
+ */
+ extern int apol_vector_compare(const apol_vector_t * a, const apol_vector_t * b, apol_vector_comp_func * cmp, void *data,
+ size_t * i);
+
+/**
+ * Sort the vector's elements within place, using an unstable sorting
+ * algorithm.
+ *
+ * @param v The vector to sort.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The expected return value from this function is
+ * less than, equal to, or greater than 0 if the first argument is
+ * less than, equal to, or greater than the second respectively. If
+ * this is NULL then treat the vector's contents as unsigned integers
+ * and sort in increasing order.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ */
+ extern void apol_vector_sort(apol_vector_t * v, apol_vector_comp_func * cmp, void *data);
+
+/**
+ * Sort the vector's elements within place (see apol_vector_sort()),
+ * and then compact vector by removing duplicate entries. The
+ * vector's free function will be used to free the memory used by
+ * non-unique elements.
+ *
+ * @param v The vector to sort.
+ * @param cmp A comparison call back for the type of element stored
+ * in the vector. The expected return value from this function is
+ * less than, equal to, or greater than 0 if the first argument is
+ * less than, equal to, or greater than the second respectively. If
+ * this is NULL then treat the vector's contents as unsigned integers
+ * and sort in increasing order.
+ * @param data Arbitrary data to pass as the comparison function's
+ * third paramater.
+ */
+ extern void apol_vector_sort_uniquify(apol_vector_t * v, apol_vector_comp_func * cmp, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APOL_VECTOR_H */