domain-trans-analysis.c File Reference


Detailed Description

Routines to perform a domain transition analysis.

Author:
Jeremy A. Mowery jmowery@tresys.com

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

Definition in file domain-trans-analysis.c.

#include "policy-query-internal.h"
#include "domain-trans-analysis-internal.h"
#include <apol/domain-trans-analysis.h>
#include <apol/bst.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>

Go to the source code of this file.


Classes

struct  apol_domain_trans_table
struct  dom_node
struct  ep_node
struct  avrule_node
struct  terule_node
struct  apol_domain_trans_analysis
struct  apol_domain_trans_result
struct  rule_map_data

Typedefs

typedef dom_node dom_node_t
typedef ep_node ep_node_t
typedef avrule_node avrule_node_t
typedef terule_node terule_node_t

Functions

int avrule_node_cmp (const void *a, const void *b, void *data __attribute__((unused)))
int avrule_node_reset (void *a, void *b __attribute__((unused)))
avrule_node_tavrule_node_create (const qpol_type_t *type, const qpol_avrule_t *rule)
int terule_node_cmp (const void *a, const void *b, void *data __attribute__((unused)))
int terule_node_reset (void *a, void *b __attribute__((unused)))
terule_node_tterule_node_create (const qpol_type_t *src, const qpol_type_t *dflt, const qpol_terule_t *rule)
int dom_node_cmp (const void *a, const void *b, void *data __attribute__((unused)))
void dom_node_free (void *x)
int dom_node_reset (void *a, void *b __attribute__((unused)))
dom_node_tdom_node_create (const qpol_type_t *type)
int ep_node_cmp (const void *a, const void *b, void *data __attribute__((unused)))
void ep_node_free (void *x)
int ep_node_reset (void *a, void *b __attribute__((unused)))
ep_node_tep_node_create (const qpol_type_t *type)
apol_domain_trans_table_tapol_domain_trans_table_new (apol_policy_t *policy)
int table_add_avrule (apol_policy_t *policy, apol_domain_trans_table_t *dta_table, const qpol_avrule_t *rule)
int table_add_terule (apol_policy_t *policy, apol_domain_trans_table_t *dta_table, const qpol_terule_t *rule)
apol_domain_trans_result_tdomain_trans_result_create ()
int apol_policy_build_domain_trans_table (apol_policy_t *policy)
 Build the table of domain transitions for a policy if not already built.
int apol_policy_domain_trans_table_build (apol_policy_t *policy)
void domain_trans_table_destroy (apol_domain_trans_table_t **table)
 Destroy the domain transition table freeing all memory used.
void apol_policy_reset_domain_trans_table (apol_policy_t *policy)
 Reset the state of the domain transition table in a policy.
void apol_domain_trans_table_reset (apol_policy_t *policy)
apol_domain_trans_analysis_tapol_domain_trans_analysis_create (void)
 Allocate and return a new domain transition analysis structure.
void apol_domain_trans_analysis_destroy (apol_domain_trans_analysis_t **dta)
 Deallocate all memory associated with the referenced domain transition analysis structure, and then set it to NULL.
int apol_domain_trans_analysis_set_direction (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, unsigned char direction)
 Set the direction of the transitions with respect to the start type.
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 search for transitions based upon whether they would be permitted.
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 begin searching using a given type.
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 matching a regular expression.
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 type.
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)
 Set the analysis to return only types having access (via allow rules) to this class with the given permission.
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 class.
int apol_domain_trans_analysis_append_perm (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *perm_name)
 Set the analysis to return only types having access (via allow rules) to this permission.
bool requires_setexec_or_type_trans (apol_policy_t *policy)
int node_list_map_fn (void *node, void *data)
apol_vector_tfind_avrules_in_node (void *node, unsigned int rule_type, const qpol_type_t *search)
apol_vector_tfind_terules_in_node (ep_node_t *node, const qpol_type_t *search, const qpol_type_t *dflt)
apol_domain_trans_result_tfind_result (apol_vector_t *local_results, const qpol_type_t *src, const qpol_type_t *tgt, const qpol_type_t *dflt)
int domain_trans_table_find_orphan_type_transitions (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results)
int domain_trans_table_get_all_forward_trans (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results, const qpol_type_t *start_type)
int domain_trans_table_get_all_reverse_trans (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results, const qpol_type_t *end_type)
int apol_domain_trans_analysis_do (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t **results)
 Execute a domain transition analysis against a particular policy.
const qpol_type_tapol_domain_trans_result_get_start_type (const apol_domain_trans_result_t *dtr)
 Return the start type of the transition in an apol_domain_trans_result node.
const qpol_type_tapol_domain_trans_result_get_entrypoint_type (const apol_domain_trans_result_t *dtr)
 Return the entrypoint type of the transition in an apol_domain_trans_result node.
const qpol_type_tapol_domain_trans_result_get_end_type (const apol_domain_trans_result_t *dtr)
 Return the end type of the transition in an apol_domain_trans_result node.
const apol_vector_tapol_domain_trans_result_get_proc_trans_rules (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.
const apol_vector_tapol_domain_trans_result_get_entrypoint_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.
const apol_vector_tapol_domain_trans_result_get_exec_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.
const apol_vector_tapol_domain_trans_result_get_setexec_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.
const apol_vector_tapol_domain_trans_result_get_type_trans_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.
int apol_domain_trans_result_is_trans_valid (const apol_domain_trans_result_t *dtr)
 Determine if the transition in an apol_domain_trans_result node is valid.
const apol_vector_tapol_domain_trans_result_get_access_rules (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.
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)
 Verify that a transition using the given three types is valid in the given policy.
apol_domain_trans_result_tapol_domain_trans_result_create_from_domain_trans_result (const apol_domain_trans_result_t *result)
 Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t object.
void domain_trans_result_free (void *dtr)
 Free all memory associated with a domain transition result, including the pointer itself.
void apol_domain_trans_result_destroy (apol_domain_trans_result_t **res)
 Free all memory used by an apol_domain_trans_result_t object and set it to NULL.

Typedef Documentation

typedef struct dom_node dom_node_t
 

Referenced by apol_domain_trans_table_verify_trans(), dom_node_cmp(), dom_node_create(), dom_node_free(), dom_node_reset(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), find_avrules_in_node(), and table_add_avrule().

typedef struct ep_node ep_node_t
 

Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), ep_node_cmp(), ep_node_create(), ep_node_free(), ep_node_reset(), find_avrules_in_node(), find_terules_in_node(), table_add_avrule(), and table_add_terule().

typedef struct avrule_node avrule_node_t
 

Referenced by avrule_node_cmp(), avrule_node_create(), avrule_node_reset(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), node_list_map_fn(), and table_add_avrule().

typedef struct terule_node terule_node_t
 

Referenced by domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), node_list_map_fn(), table_add_terule(), terule_node_cmp(), terule_node_create(), and terule_node_reset().


Function Documentation

int avrule_node_cmp const void *  a,
const void *  b,
void *data   __attribute__((unused))
[static]
 

Definition at line 105 of file domain-trans-analysis.c.

References avrule_node_t, avrule_node::rule, and avrule_node::type.

Referenced by dom_node_create(), and ep_node_create().

00106 {
00107         const avrule_node_t *an = a;
00108         const avrule_node_t *bn = b;
00109         ssize_t retv = (const char *)an->type - (const char *)bn->type;
00110         if (retv > 0)
00111                 return 1;
00112         else if (retv < 0)
00113                 return -1;
00114         retv = (const char *)an->rule - (const char *)bn->rule;
00115         if (retv > 0)
00116                 return 1;
00117         else if (retv < 0)
00118                 return -1;
00119         return 0;
00120 }

int avrule_node_reset void *  a,
void *b   __attribute__((unused))
[static]
 

Definition at line 122 of file domain-trans-analysis.c.

References avrule_node_t, and avrule_node::used.

Referenced by dom_node_reset(), and ep_node_reset().

00123 {
00124         avrule_node_t *an = a;
00125         if (!a)
00126                 return -1;
00127         an->used = false;
00128         return 0;
00129 }

avrule_node_t* avrule_node_create const qpol_type_t type,
const qpol_avrule_t rule
[static]
 

Definition at line 131 of file domain-trans-analysis.c.

References avrule_node_t, avrule_node::rule, and avrule_node::type.

Referenced by table_add_avrule().

00132 {
00133         avrule_node_t *n = calloc(1, sizeof(*n));
00134         if (!n)
00135                 return NULL;
00136 
00137         n->type = type;
00138         n->rule = rule;
00139 
00140         return n;
00141 }

int terule_node_cmp const void *  a,
const void *  b,
void *data   __attribute__((unused))
[static]
 

Definition at line 144 of file domain-trans-analysis.c.

References terule_node::dflt, terule_node::rule, terule_node::src, and terule_node_t.

Referenced by ep_node_create().

00145 {
00146         const terule_node_t *an = a;
00147         const terule_node_t *bn = b;
00148         ssize_t retv = (const char *)an->src - (const char *)bn->src;
00149         if (retv > 0)
00150                 return 1;
00151         else if (retv < 0)
00152                 return -1;
00153         retv = (const char *)an->dflt - (const char *)bn->dflt;
00154         if (retv > 0)
00155                 return 1;
00156         else if (retv < 0)
00157                 return -1;
00158         retv = (const char *)an->rule - (const char *)bn->rule;
00159         if (retv > 0)
00160                 return 1;
00161         else if (retv < 0)
00162                 return -1;
00163         return 0;
00164 }

int terule_node_reset void *  a,
void *b   __attribute__((unused))
[static]
 

Definition at line 166 of file domain-trans-analysis.c.

References terule_node_t, and terule_node::used.

Referenced by ep_node_reset().

00167 {
00168         terule_node_t *an = a;
00169         if (!a)
00170                 return -1;
00171         an->used = false;
00172         return 0;
00173 }

terule_node_t* terule_node_create const qpol_type_t src,
const qpol_type_t dflt,
const qpol_terule_t rule
[static]
 

Definition at line 175 of file domain-trans-analysis.c.

References terule_node::dflt, terule_node::rule, terule_node::src, and terule_node_t.

Referenced by table_add_terule().

00176 {
00177         terule_node_t *n = calloc(1, sizeof(*n));
00178         if (!n)
00179                 return NULL;
00180 
00181         n->src = src;
00182         n->dflt = dflt;
00183         n->rule = rule;
00184 
00185         return n;
00186 }

int dom_node_cmp const void *  a,
const void *  b,
void *data   __attribute__((unused))
[static]
 

Definition at line 189 of file domain-trans-analysis.c.

References dom_node_t, and dom_node::type.

Referenced by apol_domain_trans_table_new().

00190 {
00191         const dom_node_t *an = a;
00192         const dom_node_t *bn = b;
00193 
00194         if ((const char *)(an->type) < (const char *)(bn->type))
00195                 return -1;
00196         else if ((const char *)(an->type) > (const char *)(bn->type))
00197                 return 1;
00198         return 0;
00199 }

void dom_node_free void *  x  )  [static]
 

Definition at line 201 of file domain-trans-analysis.c.

References apol_bst_destroy(), apol_vector_destroy(), and dom_node_t.

Referenced by apol_domain_trans_table_new(), and table_add_avrule().

00202 {
00203         if (!x)
00204                 return;
00205         apol_bst_destroy(&(((dom_node_t *) x)->process_transition_tree));
00206         apol_bst_destroy(&(((dom_node_t *) x)->entrypoint_tree));
00207         apol_vector_destroy(&(((dom_node_t *) x)->setexec_rules));
00208         free(x);
00209 }

int dom_node_reset void *  a,
void *b   __attribute__((unused))
[static]
 

Definition at line 211 of file domain-trans-analysis.c.

References apol_bst_inorder_map(), avrule_node_reset(), dom_node_t, dom_node::entrypoint_tree, and dom_node::process_transition_tree.

Referenced by apol_policy_reset_domain_trans_table().

00212 {
00213         dom_node_t *an = a;
00214         if (!a)
00215                 return -1;
00216 
00217         if (apol_bst_inorder_map(an->process_transition_tree, avrule_node_reset, NULL) < 0)
00218                 return -1;
00219         if (apol_bst_inorder_map(an->entrypoint_tree, avrule_node_reset, NULL) < 0)
00220                 return -1;
00221 
00222         return 0;
00223 }

dom_node_t* dom_node_create const qpol_type_t type  )  [static]
 

Definition at line 225 of file domain-trans-analysis.c.

References apol_bst_create(), apol_bst_destroy(), apol_vector_create(), apol_vector_destroy(), avrule_node_cmp(), dom_node_t, and dom_node::type.

Referenced by table_add_avrule().

00226 {
00227         dom_node_t *n = calloc(1, sizeof(*n));
00228         if (!n)
00229                 return NULL;
00230 
00231         n->type = type;
00232         if (!(n->process_transition_tree = apol_bst_create(avrule_node_cmp, free)) ||
00233             !(n->entrypoint_tree = apol_bst_create(avrule_node_cmp, free)) || !(n->setexec_rules = apol_vector_create(NULL))) {
00234                 apol_bst_destroy(&n->process_transition_tree);
00235                 apol_bst_destroy(&n->entrypoint_tree);
00236                 apol_vector_destroy(&n->setexec_rules);
00237                 free(n);
00238                 return NULL;
00239         }
00240 
00241         return n;
00242 }

int ep_node_cmp const void *  a,
const void *  b,
void *data   __attribute__((unused))
[static]
 

Definition at line 245 of file domain-trans-analysis.c.

References ep_node_t, and ep_node::type.

Referenced by apol_domain_trans_table_new().

00246 {
00247         const ep_node_t *an = a;
00248         const ep_node_t *bn = b;
00249 
00250         if ((const char *)(an->type) < (const char *)(bn->type))
00251                 return -1;
00252         else if ((const char *)(an->type) > (const char *)(bn->type))
00253                 return 1;
00254         return 0;
00255 }

void ep_node_free void *  x  )  [static]
 

Definition at line 257 of file domain-trans-analysis.c.

References apol_bst_destroy(), and ep_node_t.

Referenced by apol_domain_trans_table_new(), table_add_avrule(), and table_add_terule().

00258 {
00259         if (!x)
00260                 return;
00261         apol_bst_destroy(&(((ep_node_t *) x)->type_transition_tree));
00262         apol_bst_destroy(&(((ep_node_t *) x)->execute_tree));
00263         free(x);
00264 }

int ep_node_reset void *  a,
void *b   __attribute__((unused))
[static]
 

Definition at line 266 of file domain-trans-analysis.c.

References apol_bst_inorder_map(), avrule_node_reset(), ep_node_t, ep_node::execute_tree, terule_node_reset(), and ep_node::type_transition_tree.

Referenced by apol_policy_reset_domain_trans_table().

00267 {
00268         ep_node_t *an = a;
00269         if (!a)
00270                 return -1;
00271 
00272         if (apol_bst_inorder_map(an->execute_tree, avrule_node_reset, NULL) < 0)
00273                 return -1;
00274         if (apol_bst_inorder_map(an->type_transition_tree, terule_node_reset, NULL) < 0)
00275                 return -1;
00276         return 0;
00277 }

ep_node_t* ep_node_create const qpol_type_t type  )  [static]
 

Definition at line 279 of file domain-trans-analysis.c.

References apol_bst_create(), apol_bst_destroy(), avrule_node_cmp(), ep_node_t, terule_node_cmp(), and ep_node::type.

Referenced by table_add_avrule(), and table_add_terule().

00280 {
00281         ep_node_t *n = calloc(1, sizeof(*n));
00282         if (!n)
00283                 return NULL;
00284 
00285         n->type = type;
00286         if (!(n->execute_tree = apol_bst_create(avrule_node_cmp, free)) ||
00287             !(n->type_transition_tree = apol_bst_create(terule_node_cmp, free))) {
00288                 apol_bst_destroy(&n->execute_tree);
00289                 apol_bst_destroy(&n->type_transition_tree);
00290                 free(n);
00291                 return NULL;
00292         }
00293 
00294         return n;
00295 }

apol_domain_trans_table_t* apol_domain_trans_table_new apol_policy_t policy  )  [static]
 

Definition at line 298 of file domain-trans-analysis.c.

References apol_bst_create(), apol_domain_trans_table_t, apol_policy_t, dom_node_cmp(), dom_node_free(), apol_domain_trans_table::domain_table, domain_trans_table_destroy(), apol_domain_trans_table::entrypoint_table, ep_node_cmp(), ep_node_free(), and ERR.

Referenced by apol_policy_build_domain_trans_table().

00299 {
00300         apol_domain_trans_table_t *new_table = NULL;
00301         int error;
00302 
00303         if (!policy) {
00304                 ERR(policy, "%s", strerror(EINVAL));
00305                 errno = EINVAL;
00306                 return NULL;
00307         }
00308 
00309         new_table = (apol_domain_trans_table_t *) calloc(1, sizeof(apol_domain_trans_table_t));
00310         if (!new_table) {
00311                 ERR(policy, "%s", strerror(ENOMEM));
00312                 error = ENOMEM;
00313                 goto cleanup;
00314         }
00315 
00316         if (!(new_table->domain_table = apol_bst_create(dom_node_cmp, dom_node_free))) {
00317                 ERR(policy, "%s", strerror(ENOMEM));
00318                 error = ENOMEM;
00319                 goto cleanup;
00320         }
00321         if (!(new_table->entrypoint_table = apol_bst_create(ep_node_cmp, ep_node_free))) {
00322                 ERR(policy, "%s", strerror(ENOMEM));
00323                 error = ENOMEM;
00324                 goto cleanup;
00325         }
00326 
00327         return new_table;
00328       cleanup:
00329         domain_trans_table_destroy(&new_table);
00330         errno = error;
00331         return NULL;
00332 }

int table_add_avrule apol_policy_t policy,
apol_domain_trans_table_t dta_table,
const qpol_avrule_t rule
[static]
 

Definition at line 334 of file domain-trans-analysis.c.

References apol_bst_get_element(), apol_bst_insert(), apol_bst_insert_and_get(), apol_domain_trans_table_t, apol_policy_get_qpol(), apol_policy_t, apol_query_expand_type(), apol_vector_append_unique(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, avrule_node_create(), avrule_node_t, dom_node_create(), dom_node_free(), dom_node_t, apol_domain_trans_table::domain_table, apol_domain_trans_table::entrypoint_table, ep_node_create(), ep_node_free(), ep_node_t, qpol_avrule_get_perm_iter(), qpol_avrule_get_source_type(), qpol_avrule_get_target_type(), qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_policy_t, qpol_type_t, ep_node::type, and dom_node::type.

Referenced by apol_policy_build_domain_trans_table().

00335 {
00336         qpol_policy_t *qp = apol_policy_get_qpol(policy);
00337         const qpol_type_t *src;
00338         const qpol_type_t *tgt;
00339         qpol_avrule_get_source_type(qp, rule, &src);
00340         qpol_avrule_get_target_type(qp, rule, &tgt);
00341         apol_vector_t *sources = apol_query_expand_type(policy, src);
00342         apol_vector_t *targets = apol_query_expand_type(policy, tgt);
00343         bool exec = false, ep = false, proc_trans = false, setexec = false;
00344         qpol_iterator_t *iter = NULL;
00345         int error = 0;
00346         qpol_avrule_get_perm_iter(qp, rule, &iter);
00347         if (!iter || !sources || !targets) {
00348                 error = errno;
00349                 goto err;
00350         }
00351 
00352         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00353                 void *x;
00354                 qpol_iterator_get_item(iter, &x);
00355                 char *perm = x;
00356                 if (!strcmp("execute", perm))
00357                         exec = true;
00358                 if (!strcmp("entrypoint", perm))
00359                         ep = true;
00360                 if (!strcmp("transition", perm))
00361                         proc_trans = true;
00362                 if (!strcmp("setexec", perm))
00363                         setexec = true;
00364                 free(x);
00365         }
00366         qpol_iterator_destroy(&iter);
00367 
00368         if (proc_trans || ep || setexec) {
00369                 for (size_t i = 0; i < apol_vector_get_size(sources); i++) {
00370                         dom_node_t *dnode = NULL;
00371                         dom_node_t dummy = { apol_vector_get_element(sources, i), NULL, NULL, NULL };
00372                         if (apol_bst_get_element(dta_table->domain_table, &dummy, NULL, (void **)&dnode)) {
00373                                 dom_node_t *new_dnode = NULL;
00374                                 if (!(new_dnode = dom_node_create(dummy.type)) ||
00375                                     apol_bst_insert(dta_table->domain_table, (void *)new_dnode, NULL)) {
00376                                         error = errno;
00377                                         dom_node_free(new_dnode);
00378                                         goto err;
00379                                 }
00380                                 dnode = new_dnode;
00381                         }
00382                         if (setexec) {
00383                                 if (apol_vector_append_unique(dnode->setexec_rules, (void *)rule, NULL, NULL)) {
00384                                         error = errno;
00385                                         goto err;
00386                                 }
00387                         }
00388                         for (size_t j = 0; j < apol_vector_get_size(targets); j++) {
00389                                 if (proc_trans) {
00390                                         avrule_node_t *new_node =
00391                                                 avrule_node_create((const qpol_type_t *)apol_vector_get_element(targets, j), rule);
00392                                         if (!new_node ||
00393                                             apol_bst_insert_and_get(dnode->process_transition_tree, (void **)&new_node, NULL) < 0) {
00394                                                 error = errno;
00395                                                 free(new_node);
00396                                                 goto err;
00397                                         }
00398                                 }
00399                                 if (ep) {
00400                                         avrule_node_t *new_node =
00401                                                 avrule_node_create((const qpol_type_t *)apol_vector_get_element(targets, j), rule);
00402                                         if (!new_node ||
00403                                             apol_bst_insert_and_get(dnode->entrypoint_tree, (void **)&new_node, NULL) < 0) {
00404                                                 error = errno;
00405                                                 free(new_node);
00406                                                 goto err;
00407                                         }
00408                                 }
00409                         }
00410                 }
00411         }
00412         if (exec) {
00413                 for (size_t i = 0; i < apol_vector_get_size(targets); i++) {
00414                         ep_node_t *enode = NULL;
00415                         ep_node_t dummy = { apol_vector_get_element(targets, i), NULL, NULL };
00416                         if (apol_bst_get_element(dta_table->entrypoint_table, &dummy, NULL, (void **)&enode)) {
00417                                 ep_node_t *new_enode = NULL;
00418                                 if (!(new_enode = ep_node_create(dummy.type)) ||
00419                                     apol_bst_insert(dta_table->entrypoint_table, (void *)new_enode, NULL)) {
00420                                         error = errno;
00421                                         ep_node_free(new_enode);
00422                                         goto err;
00423                                 }
00424                                 enode = new_enode;
00425                         }
00426                         for (size_t j = 0; j < apol_vector_get_size(sources); j++) {
00427                                 avrule_node_t *new_node =
00428                                         avrule_node_create((const qpol_type_t *)apol_vector_get_element(sources, j), rule);
00429                                 if (!new_node || apol_bst_insert_and_get(enode->execute_tree, (void **)&new_node, NULL) < 0) {
00430                                         error = errno;
00431                                         free(new_node);
00432                                         goto err;
00433                                 }
00434                         }
00435                 }
00436         }
00437 
00438         apol_vector_destroy(&sources);
00439         apol_vector_destroy(&targets);
00440         return 0;
00441 
00442       err:
00443         qpol_iterator_destroy(&iter);
00444         apol_vector_destroy(&sources);
00445         apol_vector_destroy(&targets);
00446         errno = error;
00447         return -1;
00448 }

int table_add_terule apol_policy_t policy,
apol_domain_trans_table_t dta_table,
const qpol_terule_t rule
[static]
 

Definition at line 450 of file domain-trans-analysis.c.

References apol_bst_get_element(), apol_bst_insert(), apol_bst_insert_and_get(), apol_domain_trans_table_t, apol_policy_get_qpol(), apol_policy_t, apol_query_expand_type(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_domain_trans_table::entrypoint_table, ep_node_create(), ep_node_free(), ep_node_t, qpol_policy_t, qpol_terule_get_default_type(), qpol_terule_get_source_type(), qpol_terule_get_target_type(), qpol_type_t, terule_node_create(), terule_node_t, and ep_node::type.

Referenced by apol_policy_build_domain_trans_table().

00451 {
00452         qpol_policy_t *qp = apol_policy_get_qpol(policy);
00453         const qpol_type_t *src;
00454         const qpol_type_t *tgt;
00455         const qpol_type_t *dflt;
00456         qpol_terule_get_source_type(qp, rule, &src);
00457         qpol_terule_get_target_type(qp, rule, &tgt);
00458         qpol_terule_get_default_type(qp, rule, &dflt);
00459         apol_vector_t *sources = apol_query_expand_type(policy, src);
00460         apol_vector_t *targets = apol_query_expand_type(policy, tgt);
00461         int error = 0;
00462         for (size_t i = 0; i < apol_vector_get_size(targets); i++) {
00463                 ep_node_t *enode = NULL;
00464                 ep_node_t dummy = { apol_vector_get_element(targets, i), NULL, NULL };
00465                 if (apol_bst_get_element(dta_table->entrypoint_table, &dummy, NULL, (void **)&enode)) {
00466                         ep_node_t *new_enode = NULL;
00467                         if (!(new_enode = ep_node_create(dummy.type)) ||
00468                             apol_bst_insert(dta_table->entrypoint_table, (void *)new_enode, NULL)) {
00469                                 error = errno;
00470                                 ep_node_free(new_enode);
00471                                 goto err;
00472                         }
00473                         enode = new_enode;
00474                 }
00475                 for (size_t j = 0; j < apol_vector_get_size(sources); j++) {
00476                         terule_node_t *new_node =
00477                                 terule_node_create((const qpol_type_t *)apol_vector_get_element(sources, j), dflt, rule);
00478                         if (apol_bst_insert_and_get(enode->type_transition_tree, (void **)&new_node, NULL) < 0) {
00479                                 error = errno;
00480                                 free(new_node);
00481                                 goto err;
00482                         }
00483                 }
00484         }
00485 
00486         apol_vector_destroy(&sources);
00487         apol_vector_destroy(&targets);
00488         return 0;
00489       err:
00490         apol_vector_destroy(&sources);
00491         apol_vector_destroy(&targets);
00492         errno = error;
00493         return -1;
00494 }

apol_domain_trans_result_t* domain_trans_result_create  ) 
 

Definition at line 497 of file domain-trans-analysis.c.

References apol_domain_trans_result_destroy(), apol_domain_trans_result_t, and apol_vector_create().

Referenced by domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans().

00498 {
00499         apol_domain_trans_result_t *res = calloc(1, sizeof(*res));
00500         if (!res)
00501                 return NULL;
00502 
00503         int error = 0;
00504         if (!(res->proc_trans_rules = apol_vector_create(NULL)) || !(res->ep_rules = apol_vector_create(NULL)) ||
00505             !(res->exec_rules = apol_vector_create(NULL)) || !(res->setexec_rules = apol_vector_create(NULL)) ||
00506             !(res->type_trans_rules = apol_vector_create(NULL))) {
00507                 error = errno;
00508                 goto err;
00509         }
00510 
00511         return res;
00512       err:
00513         apol_domain_trans_result_destroy(&res);
00514         errno = error;
00515         return NULL;
00516 }

int apol_policy_build_domain_trans_table apol_policy_t policy  ) 
 

Build the table of domain transitions for a policy if not already built.

Parameters:
policy The policy for which to build the table; if the table already exists for this policy, nothing is done.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and the table will be destroyed.

Definition at line 520 of file domain-trans-analysis.c.

References apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_t, apol_domain_trans_table_new(), apol_domain_trans_table_t, apol_policy_t, apol_terule_get_by_query(), apol_terule_query_append_class(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_rules(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_policy::domain_trans_table, domain_trans_table_destroy(), ERR, qpol_avrule_t, QPOL_RULE_ALLOW, QPOL_RULE_TYPE_TRANS, qpol_terule_t, table_add_avrule(), and table_add_terule().

Referenced by apol_domain_trans_analysis_do(), apol_policy_domain_trans_table_build(), apol_types_relation_domain(), dta_init(), and inc_dom_trans_run().

00521 {
00522         int error = 0;
00523         apol_avrule_query_t *avq = NULL;
00524         apol_terule_query_t *teq = NULL;
00525         apol_vector_t *avrules = NULL;
00526         apol_vector_t *terules = NULL;
00527 
00528         if (!policy) {
00529                 ERR(policy, "%s", strerror(EINVAL));
00530                 errno = EINVAL;
00531                 return -1;
00532         }
00533 
00534         if (policy->domain_trans_table) {
00535                 return 0;              /* already built */
00536         }
00537 
00538         apol_domain_trans_table_t *dta_table = policy->domain_trans_table = apol_domain_trans_table_new(policy);
00539         if (!policy->domain_trans_table) {
00540                 error = errno;
00541                 goto err;
00542         }
00543 
00544         avq = apol_avrule_query_create();
00545         apol_avrule_query_set_rules(policy, avq, QPOL_RULE_ALLOW);
00546         apol_avrule_query_append_class(policy, avq, "file");
00547         apol_avrule_query_append_class(policy, avq, "process");
00548         apol_avrule_query_append_perm(policy, avq, "execute");
00549         apol_avrule_query_append_perm(policy, avq, "entrypoint");
00550         apol_avrule_query_append_perm(policy, avq, "transition");
00551         apol_avrule_query_append_perm(policy, avq, "setexec");
00552         if (apol_avrule_get_by_query(policy, avq, &avrules)) {
00553                 error = errno;
00554                 goto err;
00555         }
00556         apol_avrule_query_destroy(&avq);
00557         for (size_t i = 0; i < apol_vector_get_size(avrules); i++) {
00558                 if (table_add_avrule(policy, dta_table, (const qpol_avrule_t *)apol_vector_get_element(avrules, i))) {
00559                         error = errno;
00560                         goto err;
00561                 }
00562         }
00563         apol_vector_destroy(&avrules);
00564 
00565         teq = apol_terule_query_create();
00566         apol_terule_query_set_rules(policy, teq, QPOL_RULE_TYPE_TRANS);
00567         apol_terule_query_append_class(policy, teq, "process");
00568         if (apol_terule_get_by_query(policy, teq, &terules)) {
00569                 error = errno;
00570                 goto err;
00571         }
00572         apol_terule_query_destroy(&teq);
00573         for (size_t i = 0; i < apol_vector_get_size(terules); i++) {
00574                 if (table_add_terule(policy, dta_table, (const qpol_terule_t *)apol_vector_get_element(terules, i))) {
00575                         error = errno;
00576                         goto err;
00577                 }
00578         }
00579         apol_vector_destroy(&terules);
00580 
00581         return 0;
00582 
00583       err:
00584         apol_avrule_query_destroy(&avq);
00585         apol_vector_destroy(&avrules);
00586         apol_terule_query_destroy(&teq);
00587         apol_vector_destroy(&terules);
00588         domain_trans_table_destroy(&dta_table);
00589         policy->domain_trans_table = NULL;
00590         errno = error;
00591         return -1;
00592 }

int apol_policy_domain_trans_table_build apol_policy_t policy  ) 
 

Deprecated:
Use apol_policy_build_domain_trans_table().

Definition at line 594 of file domain-trans-analysis.c.

References apol_policy_build_domain_trans_table(), and apol_policy_t.

00595 {
00596         return apol_policy_build_domain_trans_table(policy);
00597 }

void domain_trans_table_destroy apol_domain_trans_table_t **  table  ) 
 

Destroy the domain transition table freeing all memory used.

Parameters:
table Reference pointer to the table to be destroyed.

Definition at line 599 of file domain-trans-analysis.c.

References apol_bst_destroy(), and apol_domain_trans_table_t.

Referenced by apol_domain_trans_table_new(), apol_policy_build_domain_trans_table(), and apol_policy_destroy().

00600 {
00601         if (!table || !(*table))
00602                 return;
00603 
00604         apol_bst_destroy(&(*table)->domain_table);
00605         apol_bst_destroy(&(*table)->entrypoint_table);
00606         free(*table);
00607         *table = NULL;
00608 }

void apol_policy_reset_domain_trans_table apol_policy_t policy  ) 
 

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.

Parameters:
policy Policy containing the table for which the state should be reset.

Definition at line 610 of file domain-trans-analysis.c.

References apol_bst_inorder_map(), apol_policy_t, dom_node_reset(), apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, and ep_node_reset().

Referenced by apol_domain_trans_table_reset(), apol_domain_trans_table_verify_trans(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), and unreachable_doms_run().

00611 {
00612         if (!policy || !policy->domain_trans_table)
00613                 return;
00614         apol_bst_inorder_map(policy->domain_trans_table->domain_table, dom_node_reset, NULL);
00615         apol_bst_inorder_map(policy->domain_trans_table->entrypoint_table, ep_node_reset, NULL);
00616         return;
00617 }

void apol_domain_trans_table_reset apol_policy_t policy  ) 
 

Deprecated:
Use apol_policy_reset_domain_trans_table().

Definition at line 619 of file domain-trans-analysis.c.

References apol_policy_reset_domain_trans_table(), and apol_policy_t.

00620 {
00621         apol_policy_reset_domain_trans_table(policy);
00622 }

apol_domain_trans_analysis_t* apol_domain_trans_analysis_create void   ) 
 

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.

Returns:
An initialized domain transition analysis structure, or NULL upon error; if an error occurs errno will be set.

Definition at line 625 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_destroy(), apol_domain_trans_analysis_t, and apol_domain_trans_analysis::valid.

Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run().

00626 {
00627         apol_domain_trans_analysis_t *new_dta = NULL;
00628         int error = 0;
00629 
00630         if (!(new_dta = calloc(1, sizeof(apol_domain_trans_analysis_t)))) {
00631                 error = errno;
00632                 goto err;
00633         }
00634 
00635         new_dta->valid = APOL_DOMAIN_TRANS_SEARCH_VALID;        /* by default search only valid transitions */
00636 
00637         return new_dta;
00638 
00639       err:
00640         apol_domain_trans_analysis_destroy(&new_dta);
00641         errno = error;
00642         return NULL;
00643 }

void apol_domain_trans_analysis_destroy apol_domain_trans_analysis_t **  dta  ) 
 

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.

Parameters:
dta Reference to a domain transition analysis structure to destroy.

Definition at line 645 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_t, apol_regex_destroy(), and apol_vector_destroy().

Referenced by apol_domain_trans_analysis_create(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run().

00646 {
00647         if (!dta || !(*dta))
00648                 return;
00649 
00650         free((*dta)->start_type);
00651         free((*dta)->result);
00652         apol_vector_destroy(&((*dta)->access_types));
00653         apol_vector_destroy(&((*dta)->access_classes));
00654         apol_vector_destroy(&((*dta)->access_perms));
00655         apol_regex_destroy(&((*dta)->result_regex));
00656         free(*dta);
00657         *dta = NULL;
00658 }

int apol_domain_trans_analysis_set_direction const apol_policy_t policy,
apol_domain_trans_analysis_t dta,
unsigned char  direction
 

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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
direction The direction to analyze using one of the two values above.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 660 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_policy_t, apol_domain_trans_analysis::direction, and ERR.

Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run().

00662 {
00663         if (!dta || (direction != APOL_DOMAIN_TRANS_DIRECTION_FORWARD && direction != APOL_DOMAIN_TRANS_DIRECTION_REVERSE)) {
00664                 ERR(policy, "Error setting analysis direction: %s", strerror(EINVAL));
00665                 errno = EINVAL;
00666                 return -1;
00667         }
00668 
00669         dta->direction = direction;
00670 
00671         return 0;
00672 }

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 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).

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
valid One of APOL_DOMAIN_TRANS_SEARCH_*.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 674 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::valid.

Referenced by dta_invalid(), inc_dom_trans_run(), and unreachable_doms_run().

00675 {
00676         if (!dta || valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH)) {
00677                 ERR(policy, "Error setting analysis validity flag: %s", strerror(EINVAL));
00678                 errno = EINVAL;
00679                 return -1;
00680         }
00681 
00682         dta->valid = valid;
00683 
00684         return 0;
00685 }

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 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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
type_name Name of the type from which to begin searching. Must be non-NULL. This string will be duplicated.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 687 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::start_type.

Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run().

00689 {
00690         char *tmp = NULL;
00691         int error = 0;
00692 
00693         if (!dta || !type_name) {
00694                 ERR(policy, "%s", strerror(EINVAL));
00695                 errno = EINVAL;
00696                 return -1;
00697         }
00698 
00699         if (!(tmp = strdup(type_name))) {
00700                 error = errno;
00701                 ERR(policy, "%s", strerror(error));
00702                 errno = error;
00703                 return -1;
00704         }
00705 
00706         free(dta->start_type);
00707         dta->start_type = tmp;
00708 
00709         return 0;
00710 }

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 matching a regular expression.

Note that the regular expression will also match types' aliases.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
result Only return results matching this regular expression, or NULL to return all types.
Returns:
0 on success, and < 0 on failure; if the call fails, errno will be set.

Definition at line 712 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_t, apol_policy_t, apol_query_set(), apol_regex_destroy(), ERR, apol_domain_trans_analysis::result, and apol_domain_trans_analysis::result_regex.

Referenced by dta_reverse_regexp().

00713 {
00714         if (!dta) {
00715                 ERR(policy, "%s", strerror(EINVAL));
00716                 errno = EINVAL;
00717                 return -1;
00718         }
00719 
00720         if (!regex) {
00721                 apol_regex_destroy(&dta->result_regex);
00722                 return 0;
00723         }
00724 
00725         return apol_query_set(policy, &dta->result, &dta->result_regex, regex);
00726 }

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 type.

This is only valid for forward analysis. 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. 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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
type_name Type to which a result must have access.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 728 of file domain-trans-analysis.c.

References apol_domain_trans_analysis::access_types, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR.

Referenced by dta_forward_access().

00730 {
00731         char *tmp = NULL;
00732         int error = 0;
00733 
00734         if (!dta) {
00735                 ERR(policy, "Error appending type to analysis: %s", strerror(EINVAL));
00736                 errno = EINVAL;
00737                 return -1;
00738         }
00739 
00740         if (!type_name) {
00741                 apol_vector_destroy(&dta->access_types);
00742                 return 0;
00743         }
00744 
00745         if (!dta->access_types) {
00746                 if (!(dta->access_types = apol_vector_create(free))) {
00747                         error = errno;
00748                         ERR(policy, "%s", strerror(error));
00749                         errno = error;
00750                         return -1;
00751                 }
00752         }
00753 
00754         if (!(tmp = strdup(type_name))) {
00755                 error = errno;
00756                 ERR(policy, "%s", strerror(error));
00757                 errno = error;
00758                 return -1;
00759         }
00760 
00761         if (apol_vector_append(dta->access_types, tmp)) {
00762                 error = errno;
00763                 free(tmp);
00764                 ERR(policy, "%s", strerror(error));
00765                 errno = error;
00766                 return -1;
00767         }
00768 
00769         return 0;
00770 }

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
 

Set the analysis to return only types having access (via allow rules) to this class with the given permission.

This is only valid for forward analysis. 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. 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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
class_name The class to which a result must have access.
perm_name The permission which a result must have for the given class.
Returns:
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()

Definition at line 772 of file domain-trans-analysis.c.

References apol_domain_trans_analysis_append_class(), apol_domain_trans_analysis_append_perm(), apol_domain_trans_analysis_t, and apol_policy_t.

00774 {
00775         if (apol_domain_trans_analysis_append_class(policy, dta, class_name))
00776                 return -1;
00777         return apol_domain_trans_analysis_append_perm(policy, dta, perm_name);
00778 }

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 class.

This is only valid for forward analysis. 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. 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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
class_name The class to which a result must have access.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 780 of file domain-trans-analysis.c.

References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR.

Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access().

00782 {
00783         char *tmp = NULL;
00784         int error = 0;
00785 
00786         if (!dta) {
00787                 ERR(policy, "Error appending class to analysis: %s", strerror(EINVAL));
00788                 errno = EINVAL;
00789                 return -1;
00790         }
00791 
00792         if (!class_name) {
00793                 apol_vector_destroy(&dta->access_classes);
00794                 return 0;
00795         }
00796 
00797         if (!dta->access_classes) {
00798                 if (!(dta->access_classes = apol_vector_create(free))) {
00799                         error = errno;
00800                         ERR(policy, "%s", strerror(error));
00801                         errno = error;
00802                         return -1;
00803                 }
00804         }
00805 
00806         if (!(tmp = strdup(class_name))) {
00807                 error = errno;
00808                 ERR(policy, "%s", strerror(error));
00809                 errno = error;
00810                 return -1;
00811         }
00812 
00813         if (apol_vector_append(dta->access_classes, tmp)) {
00814                 error = errno;
00815                 free(tmp);
00816                 ERR(policy, "%s", strerror(error));
00817                 errno = error;
00818                 return -1;
00819         }
00820 
00821         return 0;
00822 }

int apol_domain_trans_analysis_append_perm const apol_policy_t policy,
apol_domain_trans_analysis_t dta,
const char *  perm_name
 

Set the analysis to return only types having access (via allow rules) to this permission.

This is only valid for forward analysis. 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. 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.

Parameters:
policy Policy handler, to report errors.
dta Domain transition analysis to set.
perm_name The permission which a result must have.
Returns:
0 on success, and < 0 on error; if the call fails, errno will be set and dta will be unchanged.

Definition at line 824 of file domain-trans-analysis.c.

References apol_domain_trans_analysis::access_perms, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR.

Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access().

00825 {
00826         char *tmp = NULL;
00827         int error = 0;
00828 
00829         if (!dta) {
00830                 ERR(policy, "Error appending perm to analysis: %s", strerror(EINVAL));
00831                 errno = EINVAL;
00832                 return -1;
00833         }
00834 
00835         if (!perm_name) {
00836                 apol_vector_destroy(&dta->access_perms);
00837                 return 0;
00838         }
00839 
00840         if (!dta->access_perms) {
00841                 if (!(dta->access_perms = apol_vector_create(free))) {
00842                         error = errno;
00843                         ERR(policy, "%s", strerror(error));
00844                         errno = error;
00845                         return -1;
00846                 }
00847         }
00848 
00849         if (!(tmp = strdup(perm_name))) {
00850                 error = errno;
00851                 ERR(policy, "%s", strerror(error));
00852                 errno = error;
00853                 return -1;
00854         }
00855 
00856         if (apol_vector_append(dta->access_perms, tmp)) {
00857                 error = errno;
00858                 free(tmp);
00859                 ERR(policy, "%s", strerror(error));
00860                 errno = error;
00861                 return -1;
00862         }
00863 
00864         return 0;
00865 }

bool requires_setexec_or_type_trans apol_policy_t policy  )  [static]
 

Definition at line 867 of file domain-trans-analysis.c.

References apol_policy_get_qpol(), apol_policy_t, apol_policy::p, QPOL_CAP_MODULES, qpol_policy_get_policy_version(), qpol_policy_has_capability(), and qpol_policy_t.

Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans().

00868 {
00869         const qpol_policy_t *qp = apol_policy_get_qpol(policy);
00870         unsigned int policy_version = 0;
00871         qpol_policy_get_policy_version(qp, &policy_version);
00872         int is_modular = qpol_policy_has_capability(policy->p, QPOL_CAP_MODULES);
00873         return (policy_version >= 15 || is_modular);
00874 }

int node_list_map_fn void *  node,
void *  data
[static]
 

Definition at line 884 of file domain-trans-analysis.c.

References apol_vector_append(), avrule_node_t, terule_node::dflt, rule_map_data::dflt, rule_map_data::is_avnode, rule_map_data::node_list, rule_map_data::search, terule_node::src, terule_node_t, avrule_node::type, terule_node::used, and avrule_node::used.

Referenced by find_avrules_in_node(), and find_terules_in_node().

00885 {
00886         struct rule_map_data *rm = data;
00887         if (rm->is_avnode) {
00888                 avrule_node_t *anode = node;
00889                 if (anode->type == rm->search && !anode->used)
00890                         if (apol_vector_append(rm->node_list, node))
00891                                 return -1;
00892                 return 0;
00893         } else {
00894                 terule_node_t *tnode = node;
00895                 if ((!rm->search || (rm->search == tnode->src)) && (!rm->dflt || (rm->dflt == tnode->dflt)) &&
00896                     rm->search != rm->dflt && !tnode->used)
00897                         if (apol_vector_append(rm->node_list, node))
00898                                 return -1;
00899                 return 0;
00900         }
00901 }

apol_vector_t* find_avrules_in_node void *  node,
unsigned int  rule_type,
const qpol_type_t search
[static]
 

Definition at line 903 of file domain-trans-analysis.c.

References apol_bst_inorder_map(), APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_vector_create(), apol_vector_destroy(), apol_vector_t, dom_node_t, dom_node::entrypoint_tree, ep_node_t, ep_node::execute_tree, node_list_map_fn(), and dom_node::process_transition_tree.

Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans().

00904 {
00905         int error = 0;
00906         apol_vector_t *rule_nodes = apol_vector_create(NULL);   //shallow copies only
00907         struct rule_map_data data = { search, NULL, rule_nodes, true };
00908         switch (rule_type) {
00909         case APOL_DOMAIN_TRANS_RULE_PROC_TRANS:
00910         {
00911                 dom_node_t *dnode = node;
00912                 if (apol_bst_inorder_map(dnode->process_transition_tree, node_list_map_fn, (void *)&data) < 0) {
00913                         error = errno;
00914                         goto err;
00915                 }
00916                 break;
00917         }
00918         case APOL_DOMAIN_TRANS_RULE_ENTRYPOINT:
00919         {
00920                 dom_node_t *dnode = node;
00921                 if (apol_bst_inorder_map(dnode->entrypoint_tree, node_list_map_fn, (void *)&data) < 0) {
00922                         error = errno;
00923                         goto err;
00924                 }
00925                 break;
00926         }
00927         case APOL_DOMAIN_TRANS_RULE_EXEC:
00928         {
00929                 ep_node_t *enode = node;
00930                 if (apol_bst_inorder_map(enode->execute_tree, node_list_map_fn, (void *)&data) < 0) {
00931                         error = errno;
00932                         goto err;
00933                 }
00934                 break;
00935         }
00936         default:
00937         {
00938                 error = EINVAL;
00939                 goto err;
00940         }
00941         }
00942 
00943         return rule_nodes;
00944 
00945       err:
00946         apol_vector_destroy(&rule_nodes);
00947         errno = error;
00948         return NULL;
00949 }

apol_vector_t* find_terules_in_node ep_node_t node,
const qpol_type_t search,
const qpol_type_t dflt
[static]
 

Definition at line 951 of file domain-trans-analysis.c.

References apol_bst_inorder_map(), apol_vector_create(), apol_vector_destroy(), apol_vector_t, ep_node_t, node_list_map_fn(), and ep_node::type_transition_tree.

Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans().

00952 {
00953         int error = 0;
00954         apol_vector_t *rule_nodes = apol_vector_create(NULL);   //shallow copies only
00955         struct rule_map_data data = { search, dflt, rule_nodes, false };
00956         if (apol_bst_inorder_map(node->type_transition_tree, node_list_map_fn, (void *)&data) < 0) {
00957                 error = errno;
00958                 goto err;
00959         }
00960 
00961         return rule_nodes;
00962 
00963       err:
00964         apol_vector_destroy(&rule_nodes);
00965         errno = error;
00966         return NULL;
00967 }

apol_domain_trans_result_t* find_result apol_vector_t local_results,
const qpol_type_t src,
const qpol_type_t tgt,
const qpol_type_t dflt
[static]
 

Definition at line 969 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_domain_trans_result::end_type, apol_domain_trans_result::ep_type, and apol_domain_trans_result::start_type.

Referenced by domain_trans_table_find_orphan_type_transitions().

00971 {
00972         for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
00973                 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
00974                 if (res->start_type == src && res->end_type == dflt && res->ep_type == tgt)
00975                         return res;
00976         }
00977         return NULL;
00978 }

int domain_trans_table_find_orphan_type_transitions apol_policy_t policy,
apol_domain_trans_analysis_t dta,
apol_vector_t local_results
[static]
 

Definition at line 980 of file domain-trans-analysis.c.

References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_get_qpol(), apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, terule_node::dflt, apol_domain_trans_analysis::direction, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_result(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, qpol_policy_get_type_by_name(), qpol_type_t, avrule_node::rule, apol_domain_trans_result::setexec_rules, terule_node::src, apol_domain_trans_result::start_type, apol_domain_trans_analysis::start_type, terule_node_t, ep_node::type, and terule_node::used.

Referenced by domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans().

00982 {
00983         int error = 0;
00984         const qpol_type_t *search = NULL;
00985         qpol_policy_get_type_by_name(apol_policy_get_qpol(policy), dta->start_type, &search);
00986         apol_domain_trans_result_t *tmp_result = NULL;
00987         //walk ep table
00988         apol_vector_t *epnodes = apol_bst_get_vector(policy->domain_trans_table->entrypoint_table, 0);
00989         if (!epnodes)
00990                 return -1;
00991         for (size_t i = 0; i < apol_vector_get_size(epnodes); i++) {
00992                 ep_node_t *node = apol_vector_get_element(epnodes, i);
00993                 //find any unused type transitions
00994                 apol_vector_t *ttnodes = NULL;
00995                 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_FORWARD)
00996                         ttnodes = find_terules_in_node(node, search, NULL);
00997                 else
00998                         ttnodes = find_terules_in_node(node, NULL, search);
00999                 for (size_t j = 0; j < apol_vector_get_size(ttnodes); j++) {
01000                         bool add = false;
01001                         terule_node_t *tn = apol_vector_get_element(ttnodes, j);
01002                         tn->used = true;
01003                         //if missing an entrypoint rule this transition may have already been added to the results
01004                         tmp_result = find_result(local_results, tn->src, node->type, tn->dflt);
01005                         if (!tmp_result) {
01006                                 add = true;
01007                                 tmp_result = domain_trans_result_create();
01008                         }
01009                         if (!tmp_result) {
01010                                 error = errno;
01011                                 apol_vector_destroy(&ttnodes);
01012                                 goto err;
01013                         }
01014                         tmp_result->start_type = tn->src;
01015                         tmp_result->end_type = tn->dflt;
01016                         tmp_result->ep_type = node->type;
01017                         //check for exec
01018                         apol_vector_t *execrules =
01019                                 find_avrules_in_node((void *)node, APOL_DOMAIN_TRANS_RULE_EXEC, tmp_result->start_type);
01020                         for (size_t k = 0; k < apol_vector_get_size(execrules); k++) {
01021                                 avrule_node_t *n = apol_vector_get_element(execrules, k);
01022                                 if (apol_vector_append(tmp_result->exec_rules, (void *)n->rule)) {
01023                                         error = errno;
01024                                         apol_vector_destroy(&execrules);
01025                                         if (!add)
01026                                                 tmp_result = NULL;
01027                                         goto err;
01028                                 }
01029                         }
01030                         apol_vector_destroy(&execrules);
01031                         //check for proc_trans and setexec
01032                         dom_node_t dummy = { tmp_result->start_type, NULL, NULL, NULL };
01033                         dom_node_t *start_node = NULL;
01034                         apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&start_node);
01035                         if (start_node) {
01036                                 //only copy setexec_rules if a new result will be added
01037                                 if (add && apol_vector_get_size(start_node->setexec_rules)) {
01038                                         if (apol_vector_cat(tmp_result->setexec_rules, start_node->setexec_rules)) {
01039                                                 error = errno;
01040                                                 goto err;
01041                                         }
01042                                 }
01043                                 //add any unused proc_trans rules
01044                                 apol_vector_t *proc_trans_rules =
01045                                         find_avrules_in_node((void *)start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS,
01046                                                              tmp_result->end_type);
01047                                 for (size_t k = 0; k < apol_vector_get_size(proc_trans_rules); k++) {
01048                                         avrule_node_t *avr = apol_vector_get_element(proc_trans_rules, k);
01049                                         if (apol_vector_append(tmp_result->proc_trans_rules, (void *)avr->rule)) {
01050                                                 error = errno;
01051                                                 if (!add)
01052                                                         tmp_result = NULL;
01053                                                 apol_vector_destroy(&proc_trans_rules);
01054                                                 goto err;
01055                                         }
01056                                 }
01057                                 apol_vector_destroy(&proc_trans_rules);
01058                                 apol_vector_sort_uniquify(tmp_result->proc_trans_rules, NULL, NULL);
01059                         }
01060                         if (add) {
01061                                 if (apol_vector_append(local_results, (void *)tmp_result)) {
01062                                         error = errno;
01063                                         goto err;
01064                                 }
01065                         }
01066                         tmp_result = NULL;
01067                 }
01068                 apol_vector_destroy(&ttnodes);
01069         }
01070         apol_vector_destroy(&epnodes);
01071 
01072         return 0;
01073 
01074       err:
01075         apol_vector_destroy(&epnodes);
01076         apol_domain_trans_result_destroy(&tmp_result);
01077         errno = error;
01078         return -1;
01079 }

int domain_trans_table_get_all_forward_trans apol_policy_t policy,
apol_domain_trans_analysis_t dta,
apol_vector_t local_results,
const qpol_type_t start_type
[static]
 

Definition at line 1081 of file domain-trans-analysis.c.

References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, domain_trans_table_find_orphan_type_transitions(), apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, qpol_type_t, requires_setexec_or_type_trans(), terule_node::rule, avrule_node::rule, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, terule_node_t, avrule_node::type, apol_domain_trans_result::type_trans_rules, avrule_node::used, apol_domain_trans_analysis::valid, and apol_domain_trans_result::valid.

Referenced by apol_domain_trans_analysis_do().

01083 {
01084         int error = 0;
01085         //create template result this will hold common data for each step and be copied as needed
01086         apol_domain_trans_result_t *tmpl_result = domain_trans_result_create();
01087         if (!tmpl_result) {
01088                 error = errno;
01089                 goto err;
01090         }
01091         //find start node
01092         dom_node_t dummy = { start_type, NULL, NULL, NULL };
01093         dom_node_t *start_node = NULL;
01094         apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&start_node);
01095         if (start_node) {
01096                 tmpl_result->start_type = start_type;
01097                 //if needed and present record setexec
01098                 if (requires_setexec_or_type_trans(policy) && apol_vector_get_size(start_node->setexec_rules)) {
01099                         if (apol_vector_cat(tmpl_result->setexec_rules, start_node->setexec_rules)) {
01100                                 error = errno;
01101                                 goto err;
01102                         }
01103                 }
01104                 //check all proc trans to build list of end types
01105                 apol_vector_t *proc_trans_rules = apol_bst_get_vector(start_node->process_transition_tree, 0);
01106                 apol_vector_t *potential_end_types = apol_vector_create(NULL);
01107                 for (size_t i = 0; i < apol_vector_get_size(proc_trans_rules); i++) {
01108                         avrule_node_t *ptnode = apol_vector_get_element(proc_trans_rules, i);
01109                         apol_vector_append(potential_end_types, (void *)ptnode->type);
01110                 }
01111                 apol_vector_destroy(&proc_trans_rules);
01112                 apol_vector_sort_uniquify(potential_end_types, NULL, NULL);
01113                 //for each end check ep
01114                 for (size_t i = 0; i < apol_vector_get_size(potential_end_types); i++) {
01115                         dummy.type = tmpl_result->end_type = apol_vector_get_element(potential_end_types, i);
01116                         dom_node_t *end_node = NULL;
01117                         apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&end_node);
01118                         const qpol_type_t *end_type = dummy.type;
01119                         if (end_type == start_type)
01120                                 continue;
01121                         //get all proc trans rules for ths end (may be multiple due to attributes)
01122                         apol_vector_t *ptrules =
01123                                 find_avrules_in_node((void *)start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, end_type);
01124                         apol_vector_destroy(&tmpl_result->proc_trans_rules);
01125                         tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01126                         for (size_t j = 0; j < apol_vector_get_size(ptrules); j++) {
01127                                 avrule_node_t *pt_ent = apol_vector_get_element(ptrules, j);
01128                                 pt_ent->used = true;
01129                                 if (apol_vector_append(tmpl_result->proc_trans_rules, (void *)pt_ent->rule)) {
01130                                         error = errno;
01131                                         apol_vector_destroy(&ptrules);
01132                                         apol_vector_destroy(&potential_end_types);
01133                                         goto err;
01134                                 }
01135                         }
01136                         apol_vector_destroy(&ptrules);
01137                         apol_vector_sort_uniquify(tmpl_result->proc_trans_rules, NULL, NULL);
01138                         if (end_node) {
01139                                 //collect potential entrypoint types
01140                                 apol_vector_t *eprules = apol_bst_get_vector(end_node->entrypoint_tree, 0);
01141                                 apol_vector_t *potential_ep_types = apol_vector_create(NULL);
01142                                 if (!eprules || !potential_ep_types) {
01143                                         error = errno;
01144                                         apol_vector_destroy(&eprules);
01145                                         apol_vector_destroy(&potential_end_types);
01146                                         goto err;
01147                                 }
01148                                 for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01149                                         avrule_node_t *epr = apol_vector_get_element(eprules, j);
01150                                         if (apol_vector_append(potential_ep_types, (void *)epr->type)) {
01151                                                 error = errno;
01152                                                 apol_vector_destroy(&eprules);
01153                                                 apol_vector_destroy(&potential_end_types);
01154                                                 apol_vector_destroy(&potential_ep_types);
01155                                                 goto err;
01156                                         }
01157                                 }
01158                                 apol_vector_destroy(&eprules);
01159                                 apol_vector_sort_uniquify(potential_ep_types, NULL, NULL);
01160                                 //for each ep find exec by start
01161                                 for (size_t j = 0; j < apol_vector_get_size(potential_ep_types); j++) {
01162                                         tmpl_result->ep_type = apol_vector_get_element(potential_ep_types, j);
01163                                         ep_node_t edummy =
01164                                                 { (const qpol_type_t *)apol_vector_get_element(potential_ep_types, j), NULL, NULL };
01165                                         ep_node_t *epnode = NULL;
01166                                         apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&edummy, NULL,
01167                                                              (void **)&epnode);
01168                                         //get all entrypoint rules for ths end (may be multiple due to attributes)
01169                                         apol_vector_destroy(&tmpl_result->ep_rules);
01170                                         tmpl_result->ep_rules = apol_vector_create(NULL);
01171                                         if (!tmpl_result->ep_rules) {
01172                                                 error = errno;
01173                                                 apol_vector_destroy(&potential_end_types);
01174                                                 apol_vector_destroy(&potential_ep_types);
01175                                                 goto err;
01176                                         }
01177                                         eprules = find_avrules_in_node((void *)end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT,
01178                                                                        tmpl_result->ep_type);
01179                                         for (size_t k = 0; k < apol_vector_get_size(eprules); k++) {
01180                                                 avrule_node_t *ep_ent = apol_vector_get_element(eprules, k);
01181                                                 ep_ent->used = true;
01182                                                 if (apol_vector_append(tmpl_result->ep_rules, (void *)ep_ent->rule)) {
01183                                                         error = errno;
01184                                                         apol_vector_destroy(&eprules);
01185                                                         apol_vector_destroy(&potential_end_types);
01186                                                         apol_vector_destroy(&potential_ep_types);
01187                                                         goto err;
01188                                                 }
01189                                         }
01190                                         apol_vector_destroy(&eprules);
01191                                         apol_vector_sort_uniquify(tmpl_result->ep_rules, NULL, NULL);
01192                                         if (epnode) {
01193                                                 //if present find tt
01194                                                 apol_vector_destroy(&tmpl_result->type_trans_rules);
01195                                                 tmpl_result->type_trans_rules = apol_vector_create(NULL);
01196                                                 if (!tmpl_result->type_trans_rules) {
01197                                                         error = errno;
01198                                                         apol_vector_destroy(&potential_end_types);
01199                                                         apol_vector_destroy(&potential_ep_types);
01200                                                         goto err;
01201                                                 }
01202                                                 apol_vector_t *ttrules = find_terules_in_node(epnode, start_type, end_type);
01203                                                 for (size_t l = 0; l < apol_vector_get_size(ttrules); l++) {
01204                                                         terule_node_t *tn = apol_vector_get_element(ttrules, l);
01205                                                         if (apol_vector_append(tmpl_result->type_trans_rules, (void *)tn->rule)) {
01206                                                                 error = errno;
01207                                                                 apol_vector_destroy(&ttrules);
01208                                                                 apol_vector_destroy(&potential_end_types);
01209                                                                 apol_vector_destroy(&potential_ep_types);
01210                                                                 goto err;
01211                                                         }
01212                                                 }
01213                                                 apol_vector_destroy(&ttrules);
01214                                                 apol_vector_sort_uniquify(tmpl_result->type_trans_rules, NULL, NULL);
01215                                                 //find execute rules
01216                                                 apol_vector_destroy(&tmpl_result->exec_rules);
01217                                                 tmpl_result->exec_rules = apol_vector_create(NULL);
01218                                                 if (!tmpl_result->exec_rules) {
01219                                                         error = errno;
01220                                                         apol_vector_destroy(&potential_end_types);
01221                                                         apol_vector_destroy(&potential_ep_types);
01222                                                         goto err;
01223                                                 }
01224                                                 apol_vector_t *execrules =
01225                                                         find_avrules_in_node(epnode, APOL_DOMAIN_TRANS_RULE_EXEC, start_type);
01226                                                 if (apol_vector_get_size(execrules)) {
01227                                                         for (size_t l = 0; l < apol_vector_get_size(execrules); l++) {
01228                                                                 avrule_node_t *xnode = apol_vector_get_element(execrules, l);
01229                                                                 //do not mark xnode as used here; it is valid to re-use it.
01230                                                                 if (apol_vector_append
01231                                                                     (tmpl_result->exec_rules, (void *)xnode->rule)) {
01232                                                                         error = errno;
01233                                                                         apol_vector_destroy(&execrules);
01234                                                                         apol_vector_destroy(&potential_end_types);
01235                                                                         apol_vector_destroy(&potential_ep_types);
01236                                                                         goto err;
01237                                                                 }
01238                                                         }
01239                                                         apol_vector_destroy(&execrules);
01240                                                         apol_vector_sort_uniquify(tmpl_result->exec_rules, NULL, NULL);
01241                                                         //found everything possible add a result
01242                                                         apol_domain_trans_result_t *tmp =
01243                                                                 apol_domain_trans_result_create_from_domain_trans_result
01244                                                                 (tmpl_result);
01245                                                         if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01246                                                                 error = errno;
01247                                                                 apol_domain_trans_result_destroy(&tmp);
01248                                                                 apol_vector_destroy(&potential_end_types);
01249                                                                 apol_vector_destroy(&potential_ep_types);
01250                                                                 goto err;
01251                                                         }
01252                                                         //reset execute rules
01253                                                         apol_vector_destroy(&tmpl_result->exec_rules);
01254                                                         tmpl_result->exec_rules = apol_vector_create(NULL);
01255                                                         if (!tmpl_result->exec_rules) {
01256                                                                 error = errno;
01257                                                                 apol_vector_destroy(&potential_end_types);
01258                                                                 apol_vector_destroy(&potential_ep_types);
01259                                                                 goto err;
01260                                                         }
01261                                                         //reset type transition rules
01262                                                         apol_vector_destroy(&tmpl_result->type_trans_rules);
01263                                                         tmpl_result->type_trans_rules = apol_vector_create(NULL);
01264                                                         if (!tmpl_result->type_trans_rules) {
01265                                                                 error = errno;
01266                                                                 apol_vector_destroy(&potential_end_types);
01267                                                                 apol_vector_destroy(&potential_ep_types);
01268                                                                 goto err;
01269                                                         }
01270                                                 } else {
01271                                                         //have proc_trans and entrypoint but no execute
01272                                                         apol_domain_trans_result_t *tmp =
01273                                                                 apol_domain_trans_result_create_from_domain_trans_result
01274                                                                 (tmpl_result);
01275                                                         if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01276                                                                 error = errno;
01277                                                                 apol_domain_trans_result_destroy(&tmp);
01278                                                                 apol_vector_destroy(&potential_end_types);
01279                                                                 apol_vector_destroy(&potential_ep_types);
01280                                                                 goto err;
01281                                                         }
01282                                                 }
01283                                                 apol_vector_destroy(&execrules);
01284                                         } else {
01285                                                 //have proc_trans and entrypoint but no execute
01286                                                 apol_domain_trans_result_t *tmp =
01287                                                         apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01288                                                 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01289                                                         error = errno;
01290                                                         apol_domain_trans_result_destroy(&tmp);
01291                                                         apol_vector_destroy(&potential_end_types);
01292                                                         apol_vector_destroy(&potential_ep_types);
01293                                                         goto err;
01294                                                 }
01295                                         }
01296                                         //reset entrypoint rules
01297                                         apol_vector_destroy(&tmpl_result->ep_rules);
01298                                         tmpl_result->ep_rules = apol_vector_create(NULL);
01299                                         if (!tmpl_result->ep_rules) {
01300                                                 error = errno;
01301                                                 apol_vector_destroy(&potential_end_types);
01302                                                 apol_vector_destroy(&potential_ep_types);
01303                                                 goto err;
01304                                         }
01305                                 }
01306                                 apol_vector_destroy(&potential_ep_types);
01307                         } else {
01308                                 //have proc_trans but end has no ep
01309                                 apol_domain_trans_result_t *tmp =
01310                                         apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01311                                 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01312                                         error = errno;
01313                                         apol_domain_trans_result_destroy(&tmp);
01314                                         goto err;
01315                                 }
01316                         }
01317                 }
01318                 apol_vector_destroy(&potential_end_types);
01319                 //validate all
01320                 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01321                         apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01322                         if (res->start_type && res->ep_type && res->end_type && apol_vector_get_size(res->proc_trans_rules) &&
01323                             apol_vector_get_size(res->ep_rules) && apol_vector_get_size(res->exec_rules) &&
01324                             (requires_setexec_or_type_trans(policy)
01325                              ? (apol_vector_get_size(res->setexec_rules) || apol_vector_get_size(res->type_trans_rules)) : true)) {
01326                                 res->valid = true;
01327                         }
01328                 }
01329         }
01330         //iff looking for invalid find orphan type_transition rules
01331         if (dta->valid & APOL_DOMAIN_TRANS_SEARCH_INVALID) {
01332                 if (domain_trans_table_find_orphan_type_transitions(policy, dta, local_results)) {
01333                         error = errno;
01334                         goto err;
01335                 }
01336         }
01337         apol_domain_trans_result_destroy(&tmpl_result);
01338 
01339         return 0;
01340       err:
01341         apol_domain_trans_result_destroy(&tmpl_result);
01342         errno = error;
01343         return -1;
01344 }

int domain_trans_table_get_all_reverse_trans apol_policy_t policy,
apol_domain_trans_analysis_t dta,
apol_vector_t local_results,
const qpol_type_t end_type
[static]
 

Definition at line 1346 of file domain-trans-analysis.c.

References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, domain_trans_table_find_orphan_type_transitions(), apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, requires_setexec_or_type_trans(), terule_node::rule, avrule_node::rule, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, terule_node_t, avrule_node::type, apol_domain_trans_result::type_trans_rules, terule_node::used, avrule_node::used, apol_domain_trans_analysis::valid, and apol_domain_trans_result::valid.

Referenced by apol_domain_trans_analysis_do().

01348 {
01349         int error = 0;
01350         //create template result this will hold common data for each step and be copied as needed
01351         apol_domain_trans_result_t *tmpl_result = domain_trans_result_create();
01352         if (!tmpl_result) {
01353                 error = errno;
01354                 goto err;
01355         }
01356         //find end node
01357         dom_node_t dummy = { end_type, NULL, NULL, NULL };
01358         dom_node_t *end_node = NULL;
01359         apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&end_node);
01360         if (end_node) {
01361                 tmpl_result->end_type = end_type;
01362                 //collect potential entrypoint types
01363                 apol_vector_t *eprules = apol_bst_get_vector(end_node->entrypoint_tree, 0);
01364                 apol_vector_t *potential_ep_types = apol_vector_create(NULL);
01365                 if (!eprules || !potential_ep_types) {
01366                         error = errno;
01367                         apol_vector_destroy(&eprules);
01368                         goto err;
01369                 }
01370                 for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01371                         avrule_node_t *epr = apol_vector_get_element(eprules, j);
01372                         if (apol_vector_append(potential_ep_types, (void *)epr->type)) {
01373                                 error = errno;
01374                                 apol_vector_destroy(&eprules);
01375                                 apol_vector_destroy(&potential_ep_types);
01376                                 goto err;
01377                         }
01378                 }
01379                 apol_vector_destroy(&eprules);
01380                 apol_vector_sort_uniquify(potential_ep_types, NULL, NULL);
01381                 for (size_t i = 0; i < apol_vector_get_size(potential_ep_types); i++) {
01382                         tmpl_result->ep_type = apol_vector_get_element(potential_ep_types, i);
01383                         //get all ep rules for this end (may be multiple due to attributes)
01384                         eprules = find_avrules_in_node((void *)end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, tmpl_result->ep_type);
01385                         apol_vector_destroy(&tmpl_result->ep_rules);
01386                         tmpl_result->ep_rules = apol_vector_create(NULL);
01387                         for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01388                                 avrule_node_t *ep_ent = apol_vector_get_element(eprules, j);
01389                                 ep_ent->used = true;
01390                                 if (apol_vector_append(tmpl_result->ep_rules, (void *)ep_ent->rule)) {
01391                                         error = errno;
01392                                         apol_vector_destroy(&eprules);
01393                                         apol_vector_destroy(&potential_ep_types);
01394                                         goto err;
01395                                 }
01396                         }
01397                         apol_vector_destroy(&eprules);
01398                         apol_vector_sort_uniquify(tmpl_result->ep_rules, NULL, NULL);
01399                         ep_node_t edummy = { tmpl_result->ep_type, NULL, NULL };
01400                         ep_node_t *epnode = NULL;
01401                         apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&edummy, NULL, (void **)&epnode);
01402                         //for each ep find exec rules to generate list of potential start types
01403                         if (epnode) {
01404                                 apol_vector_t *execrules = apol_bst_get_vector(epnode->execute_tree, 0);
01405                                 apol_vector_t *potential_start_types = apol_vector_create(NULL);
01406                                 if (!execrules || !potential_start_types) {
01407                                         error = errno;
01408                                         apol_vector_destroy(&execrules);
01409                                         goto err;
01410                                 }
01411                                 for (size_t k = 0; k < apol_vector_get_size(execrules); k++) {
01412                                         avrule_node_t *n = apol_vector_get_element(execrules, k);
01413                                         if (apol_vector_append(potential_start_types, (void *)n->type)) {
01414                                                 error = errno;
01415                                                 apol_vector_destroy(&execrules);
01416                                                 apol_vector_destroy(&potential_start_types);
01417                                                 apol_vector_destroy(&potential_ep_types);
01418                                                 goto err;
01419                                         }
01420                                 }
01421                                 apol_vector_destroy(&execrules);
01422                                 apol_vector_sort_uniquify(potential_start_types, NULL, NULL);
01423                                 for (size_t k = 0; k < apol_vector_get_size(potential_start_types); k++) {
01424                                         tmpl_result->start_type = apol_vector_get_element(potential_start_types, k);
01425                                         //no transition to self
01426                                         if (tmpl_result->end_type == tmpl_result->start_type)
01427                                                 continue;
01428                                         //get all execute rule for this start type
01429                                         apol_vector_t *exec_rules =
01430                                                 find_avrules_in_node((void *)epnode, APOL_DOMAIN_TRANS_RULE_EXEC,
01431                                                                      tmpl_result->start_type);
01432                                         apol_vector_destroy(&tmpl_result->exec_rules);
01433                                         tmpl_result->exec_rules = apol_vector_create(NULL);
01434                                         for (size_t l = 0; l < apol_vector_get_size(exec_rules); l++) {
01435                                                 avrule_node_t *n = apol_vector_get_element(exec_rules, l);
01436                                                 n->used = true;
01437                                                 if (apol_vector_append(tmpl_result->exec_rules, (void *)n->rule)) {
01438                                                         error = errno;
01439                                                         apol_vector_destroy(&exec_rules);
01440                                                         apol_vector_destroy(&potential_start_types);
01441                                                         apol_vector_destroy(&potential_ep_types);
01442                                                         goto err;
01443                                                 }
01444                                         }
01445                                         apol_vector_destroy(&exec_rules);
01446                                         apol_vector_sort_uniquify(tmpl_result->exec_rules, NULL, NULL);
01447                                         //check for type transition rules
01448                                         apol_vector_t *ttrules =
01449                                                 find_terules_in_node(epnode, tmpl_result->start_type, tmpl_result->end_type);
01450                                         apol_vector_destroy(&tmpl_result->type_trans_rules);
01451                                         tmpl_result->type_trans_rules = apol_vector_create(NULL);
01452                                         if (!tmpl_result->type_trans_rules) {
01453                                                 error = errno;
01454                                                 apol_vector_destroy(&ttrules);
01455                                                 apol_vector_destroy(&potential_start_types);
01456                                                 apol_vector_destroy(&potential_ep_types);
01457                                                 goto err;
01458                                         }
01459                                         for (size_t l = 0; l < apol_vector_get_size(ttrules); l++) {
01460                                                 terule_node_t *n = apol_vector_get_element(ttrules, l);
01461                                                 n->used = true;
01462                                                 if (apol_vector_append(tmpl_result->type_trans_rules, (void *)n->rule)) {
01463                                                         error = errno;
01464                                                         apol_vector_destroy(&ttrules);
01465                                                         apol_vector_destroy(&potential_start_types);
01466                                                         apol_vector_destroy(&potential_ep_types);
01467                                                         goto err;
01468                                                 }
01469                                         }
01470                                         apol_vector_destroy(&ttrules);
01471                                         apol_vector_sort_uniquify(tmpl_result->type_trans_rules, NULL, NULL);
01472                                         dummy.type = tmpl_result->start_type;
01473                                         dom_node_t *start_node = NULL;
01474                                         apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL,
01475                                                              (void **)&start_node);
01476                                         if (start_node) {
01477                                                 //for each start check setexec if needed
01478                                                 if (requires_setexec_or_type_trans(policy)) {
01479                                                         apol_vector_destroy(&tmpl_result->setexec_rules);
01480                                                         tmpl_result->setexec_rules = apol_vector_create(NULL);
01481                                                         if (!tmpl_result->setexec_rules ||
01482                                                             apol_vector_cat(tmpl_result->setexec_rules,
01483                                                                             start_node->setexec_rules)) {
01484                                                                 error = errno;
01485                                                                 apol_vector_destroy(&potential_start_types);
01486                                                                 apol_vector_destroy(&potential_ep_types);
01487                                                                 goto err;
01488                                                         }
01489                                                 }
01490                                                 //for each start find pt
01491                                                 apol_vector_destroy(&tmpl_result->proc_trans_rules);
01492                                                 tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01493                                                 if (!tmpl_result->proc_trans_rules) {
01494                                                         error = errno;
01495                                                         apol_vector_destroy(&potential_start_types);
01496                                                         apol_vector_destroy(&potential_ep_types);
01497                                                         goto err;
01498                                                 }
01499                                                 apol_vector_t *pt_rules = NULL;
01500                                                 pt_rules =
01501                                                         find_avrules_in_node(start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS,
01502                                                                              tmpl_result->end_type);
01503                                                 if (apol_vector_get_size(pt_rules)) {
01504                                                         for (size_t l = 0; l < apol_vector_get_size(pt_rules); l++) {
01505                                                                 avrule_node_t *n = apol_vector_get_element(pt_rules, l);
01506                                                                 apol_vector_append(tmpl_result->proc_trans_rules, (void *)n->rule);
01507                                                         }
01508                                                         apol_vector_destroy(&pt_rules);
01509                                                         apol_vector_sort_uniquify(tmpl_result->proc_trans_rules, NULL, NULL);
01510                                                         // have all possible rules add this entry
01511                                                         apol_domain_trans_result_t *tmp =
01512                                                                 apol_domain_trans_result_create_from_domain_trans_result
01513                                                                 (tmpl_result);
01514                                                         if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01515                                                                 error = errno;
01516                                                                 apol_domain_trans_result_destroy(&tmp);
01517                                                                 apol_vector_destroy(&potential_start_types);
01518                                                                 apol_vector_destroy(&potential_ep_types);
01519                                                                 goto err;
01520                                                         }
01521                                                         //reset process transition rules
01522                                                         apol_vector_destroy(&tmpl_result->proc_trans_rules);
01523                                                         tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01524                                                         if (!tmpl_result->proc_trans_rules) {
01525                                                                 error = errno;
01526                                                                 apol_vector_destroy(&potential_start_types);
01527                                                                 apol_vector_destroy(&potential_ep_types);
01528                                                                 goto err;
01529                                                         }
01530                                                         //reset setexec rules
01531                                                         apol_vector_destroy(&tmpl_result->setexec_rules);
01532                                                         tmpl_result->setexec_rules = apol_vector_create(NULL);
01533                                                         if (!tmpl_result->setexec_rules) {
01534                                                                 error = errno;
01535                                                                 apol_vector_destroy(&potential_start_types);
01536                                                                 apol_vector_destroy(&potential_ep_types);
01537                                                                 goto err;
01538                                                         }
01539                                                 } else {
01540                                                         //have entrypoint and execute rules but no process transition rule
01541                                                         apol_domain_trans_result_t *tmp =
01542                                                                 apol_domain_trans_result_create_from_domain_trans_result
01543                                                                 (tmpl_result);
01544                                                         if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01545                                                                 error = errno;
01546                                                                 apol_domain_trans_result_destroy(&tmp);
01547                                                                 apol_vector_destroy(&potential_start_types);
01548                                                                 apol_vector_destroy(&potential_ep_types);
01549                                                                 apol_vector_destroy(&pt_rules);
01550                                                                 goto err;
01551                                                         }
01552                                                 }
01553                                                 apol_vector_destroy(&pt_rules);
01554                                         } else {
01555                                                 //have entrypoint and execute rules but no process transition rule
01556                                                 apol_domain_trans_result_t *tmp =
01557                                                         apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01558                                                 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01559                                                         error = errno;
01560                                                         apol_domain_trans_result_destroy(&tmp);
01561                                                         apol_vector_destroy(&potential_start_types);
01562                                                         apol_vector_destroy(&potential_ep_types);
01563                                                         goto err;
01564                                                 }
01565                                         }
01566                                         //reset execute rules
01567                                         apol_vector_destroy(&tmpl_result->exec_rules);
01568                                         tmpl_result->exec_rules = apol_vector_create(NULL);
01569                                         if (!tmpl_result->exec_rules) {
01570                                                 error = errno;
01571                                                 apol_vector_destroy(&potential_start_types);
01572                                                 apol_vector_destroy(&potential_ep_types);
01573                                                 goto err;
01574                                         }
01575                                         //reset type transition rules
01576                                         apol_vector_destroy(&tmpl_result->type_trans_rules);
01577                                         tmpl_result->type_trans_rules = apol_vector_create(NULL);
01578                                         if (!tmpl_result->type_trans_rules) {
01579                                                 error = errno;
01580                                                 apol_vector_destroy(&potential_start_types);
01581                                                 apol_vector_destroy(&potential_ep_types);
01582                                                 goto err;
01583                                         }
01584                                 }
01585                                 apol_vector_destroy(&potential_start_types);
01586                         } else {
01587                                 //have entrypoint but no exec
01588                                 apol_domain_trans_result_t *tmp =
01589                                         apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01590                                 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01591                                         error = errno;
01592                                         apol_domain_trans_result_destroy(&tmp);
01593                                         goto err;
01594                                 }
01595                         }
01596                 }
01597                 apol_vector_destroy(&potential_ep_types);
01598 
01599                 //validate all
01600                 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01601                         apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01602                         if (res->start_type && res->ep_type && res->end_type && apol_vector_get_size(res->proc_trans_rules) &&
01603                             apol_vector_get_size(res->ep_rules) && apol_vector_get_size(res->exec_rules) &&
01604                             (requires_setexec_or_type_trans(policy)
01605                              ? (apol_vector_get_size(res->setexec_rules) || apol_vector_get_size(res->type_trans_rules)) : true)) {
01606                                 res->valid = true;
01607                         }
01608                 }
01609         }
01610         //iff looking for invalid find orphan type_transition rules
01611         if (dta->valid & APOL_DOMAIN_TRANS_SEARCH_INVALID) {
01612                 if (domain_trans_table_find_orphan_type_transitions(policy, dta, local_results)) {
01613                         error = errno;
01614                         goto err;
01615                 }
01616         }
01617 
01618         apol_domain_trans_result_destroy(&tmpl_result);
01619         return 0;
01620 
01621       err:
01622         apol_domain_trans_result_destroy(&tmpl_result);
01623         errno = error;
01624         return -1;
01625 }

int apol_domain_trans_analysis_do apol_policy_t policy,
apol_domain_trans_analysis_t dta,
apol_vector_t **  results
 

Execute a domain transition analysis against a particular policy.

Parameters:
policy Policy containing the table to use.
dta A non-NULL structure containng parameters for analysis.
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.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and *results will be NULL.
See also:
apol_policy_reset_domain_trans_table()

Definition at line 1627 of file domain-trans-analysis.c.

References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis::access_perms, apol_domain_trans_result::access_rules, apol_domain_trans_analysis::access_types, apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_set_source(), apol_avrule_query_set_target(), apol_avrule_query_t, apol_compare_type(), apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_t, apol_policy_build_domain_trans_table(), apol_policy_get_qpol(), apol_policy_t, APOL_QUERY_REGEX, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_remove(), apol_vector_t, apol_domain_trans_analysis::direction, domain_trans_result_free(), apol_policy::domain_trans_table, domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), apol_domain_trans_result::end_type, ERR, apol_policy::p, qpol_policy_get_type_by_name(), QPOL_RULE_ALLOW, qpol_type_get_isattr(), qpol_type_get_name(), qpol_type_t, apol_domain_trans_analysis::result, apol_domain_trans_analysis::result_regex, apol_domain_trans_result::start_type, apol_domain_trans_analysis::start_type, apol_domain_trans_result::valid, and apol_domain_trans_analysis::valid.

Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run().

01628 {
01629         apol_vector_t *local_results = NULL;
01630         apol_avrule_query_t *accessq = NULL;
01631         int error = 0;
01632         if (!results)
01633                 *results = NULL;
01634         if (!policy || !dta || !results) {
01635                 ERR(policy, "%s", strerror(EINVAL));
01636                 errno = EINVAL;
01637                 return -1;
01638         }
01639 
01640         /* build table if not already present */
01641         if (!(policy->domain_trans_table)) {
01642                 if (apol_policy_build_domain_trans_table(policy))
01643                         return -1;     /* errors already reported by build function */
01644         }
01645 
01646         /* validate analysis options */
01647         if (dta->direction == 0 || dta->valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH) || !(dta->start_type)) {
01648                 error = EINVAL;
01649                 ERR(policy, "%s", strerror(EINVAL));
01650                 goto err;
01651         }
01652         size_t num_atypes = apol_vector_get_size(dta->access_types);
01653         size_t num_aclasses = apol_vector_get_size(dta->access_classes);
01654         size_t num_aprems = apol_vector_get_size(dta->access_perms);
01655         if ((num_atypes == 0 && (num_aclasses != 0 || num_aprems != 0)) ||
01656             (num_aclasses == 0 && (num_atypes != 0 || num_aprems != 0)) ||
01657             (num_aprems == 0 && (num_aclasses != 0 || num_atypes != 0))) {
01658                 error = EINVAL;
01659                 ERR(policy, "%s", strerror(EINVAL));
01660                 goto err;
01661         }
01662 
01663         /* get starting type */
01664         const qpol_type_t *start_type = NULL;
01665         if (qpol_policy_get_type_by_name(policy->p, dta->start_type, &start_type)) {
01666                 error = errno;
01667                 ERR(policy, "Unable to perform analysis: Invalid starting type %s", dta->start_type);
01668                 goto err;
01669         }
01670         unsigned char isattr = 0;
01671         qpol_type_get_isattr(policy->p, start_type, &isattr);
01672         if (isattr) {
01673                 ERR(policy, "%s", "Attributes are not valid here.");
01674                 error = EINVAL;
01675                 goto err;
01676         }
01677 
01678         local_results = apol_vector_create(domain_trans_result_free);
01679         /* get all transitions for the requested direction */
01680         if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01681                 if (domain_trans_table_get_all_reverse_trans(policy, dta, local_results, start_type)) {
01682                         error = errno;
01683                         goto err;
01684                 }
01685         } else {
01686                 if (domain_trans_table_get_all_forward_trans(policy, dta, local_results, start_type)) {
01687                         error = errno;
01688                         goto err;
01689                 }
01690         }
01691 
01692         /* if requested, filter by validity */
01693         if (dta->valid != APOL_DOMAIN_TRANS_SEARCH_BOTH) {
01694                 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01695                         apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01696                         if (res->valid != (dta->valid == APOL_DOMAIN_TRANS_SEARCH_VALID)) {
01697                                 apol_vector_remove(local_results, i);
01698                                 domain_trans_result_free(res);
01699                         } else {
01700                                 i++;
01701                         }
01702                 }
01703         }
01704 
01705         /* if filtering by result type, do that now */
01706         if (dta->result) {
01707                 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01708                         apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01709                         const qpol_type_t *type = NULL;
01710                         if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01711                                 type = res->start_type;
01712                         } else {
01713                                 type = res->end_type;
01714                         }
01715                         int compval = apol_compare_type(policy, type, dta->result, APOL_QUERY_REGEX, &dta->result_regex);
01716                         if (compval < 0) {
01717                                 error = errno;
01718                                 goto err;
01719                         } else if (compval > 0) {
01720                                 i++;
01721                         } else {
01722                                 apol_vector_remove(local_results, i);
01723                                 domain_trans_result_free(res);
01724                         }
01725                 }
01726         }
01727 
01728         /* finally do access filtering */
01729         if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_FORWARD && num_atypes && num_aclasses && num_aprems) {
01730                 accessq = apol_avrule_query_create();
01731                 apol_avrule_query_set_rules(policy, accessq, QPOL_RULE_ALLOW);
01732                 for (size_t i = 0; i < num_aclasses; i++) {
01733                         if (apol_avrule_query_append_class
01734                             (policy, accessq, (char *)apol_vector_get_element(dta->access_classes, i))) {
01735                                 error = errno;
01736                                 goto err;
01737                         }
01738                 }
01739                 for (size_t i = 0; i < num_aprems; i++) {
01740                         if (apol_avrule_query_append_perm(policy, accessq, (char *)apol_vector_get_element(dta->access_perms, i))) {
01741                                 error = errno;
01742                                 goto err;
01743                         }
01744                 }
01745                 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01746                         const char *end_name = NULL;
01747                         apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01748                         if (qpol_type_get_name(apol_policy_get_qpol(policy), res->end_type, &end_name) ||
01749                             apol_avrule_query_set_source(policy, accessq, end_name, 1)) {
01750                                 error = errno;
01751                                 goto err;
01752                         }
01753                         apol_vector_t *tmp_access = apol_vector_create(NULL);
01754                         for (size_t j = 0; j < num_atypes; j++) {
01755                                 if (apol_avrule_query_set_target
01756                                     (policy, accessq, (char *)apol_vector_get_element(dta->access_types, j), 1)) {
01757                                         error = errno;
01758                                         apol_vector_destroy(&tmp_access);
01759                                         goto err;
01760                                 }
01761                                 apol_vector_t *cur_tgt_v = NULL;
01762                                 apol_avrule_get_by_query(policy, accessq, &cur_tgt_v);
01763                                 apol_vector_cat(tmp_access, cur_tgt_v);
01764                                 apol_vector_destroy(&cur_tgt_v);
01765                         }
01766                         if (apol_vector_get_size(tmp_access)) {
01767                                 res->access_rules = tmp_access;
01768                                 tmp_access = NULL;
01769                                 i++;
01770                         } else {
01771                                 apol_vector_remove(local_results, i);
01772                                 domain_trans_result_free(res);
01773                         }
01774                         apol_vector_destroy(&tmp_access);
01775                 }
01776                 apol_avrule_query_destroy(&accessq);
01777         }
01778 
01779         *results = apol_vector_create(domain_trans_result_free);
01780         if (!(*results)) {
01781                 error = errno;
01782                 goto err;
01783         }
01784         for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01785                 apol_domain_trans_result_t *res =
01786                         apol_domain_trans_result_create_from_domain_trans_result((apol_domain_trans_result_t *)
01787                                                                                  apol_vector_get_element(local_results, i));
01788                 if (!res || apol_vector_append(*results, (void *)res)) {
01789                         error = errno;
01790                         domain_trans_result_free(res);
01791                         goto err;
01792                 }
01793         }
01794         apol_vector_destroy(&local_results);
01795 
01796         return 0;
01797       err:
01798         apol_vector_destroy(&local_results);
01799         apol_vector_destroy(results);
01800         apol_avrule_query_destroy(&accessq);
01801         errno = error;
01802         return -1;
01803 }

const qpol_type_t* apol_domain_trans_result_get_start_type const apol_domain_trans_result_t dtr  ) 
 

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.

Parameters:
dtr Domain transition result node.
Returns:
Pointer to the start type of the transition.

Definition at line 1807 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, qpol_type_t, and apol_domain_trans_result::start_type.

Referenced by dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run().

01808 {
01809         if (dtr) {
01810                 return dtr->start_type;
01811         } else {
01812                 errno = EINVAL;
01813                 return NULL;
01814         }
01815 }

const qpol_type_t* apol_domain_trans_result_get_entrypoint_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.

Parameters:
dtr Domain transition result node.
Returns:
Pointer to the entrypoint type of the transition.

Definition at line 1817 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_domain_trans_result::ep_type, and qpol_type_t.

Referenced by dta_forward(), dta_forward_multi_end(), dta_invalid(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run().

01818 {
01819         if (dtr) {
01820                 return dtr->ep_type;
01821         } else {
01822                 errno = EINVAL;
01823                 return NULL;
01824         }
01825 }

const qpol_type_t* apol_domain_trans_result_get_end_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.

Parameters:
dtr Domain transition result node.
Returns:
Pointer to the start type of the transition.

Definition at line 1827 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_domain_trans_result::end_type, and qpol_type_t.

Referenced by apol_types_relation_clone_domaintrans(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), and inc_dom_trans_run().

01828 {
01829         if (dtr) {
01830                 return dtr->end_type;
01831         } else {
01832                 errno = EINVAL;
01833                 return NULL;
01834         }
01835 }

const apol_vector_t* apol_domain_trans_result_get_proc_trans_rules 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.

Parameters:
dtr Domain transition result node.
Returns:
Vector of qpol_avrule_t relative to the policy originally used to generate the results.

Definition at line 1837 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::proc_trans_rules.

Referenced by dta_invalid().

01838 {
01839         if (dtr) {
01840                 return dtr->proc_trans_rules;
01841         } else {
01842                 errno = EINVAL;
01843                 return NULL;
01844         }
01845 }

const apol_vector_t* apol_domain_trans_result_get_entrypoint_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.

Returns:
Vector of qpol_avrule_t relative to the policy originally used to generate the results.

Definition at line 1847 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::ep_rules.

Referenced by dta_invalid().

01848 {
01849         if (dtr) {
01850                 return dtr->ep_rules;
01851         } else {
01852                 errno = EINVAL;
01853                 return NULL;
01854         }
01855 }

const apol_vector_t* apol_domain_trans_result_get_exec_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.

Returns:
Vector of qpol_avrule_t relative to the policy originally used to generate the results.

Definition at line 1857 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::exec_rules.

Referenced by dta_invalid().

01858 {
01859         if (dtr) {
01860                 return dtr->exec_rules;
01861         } else {
01862                 errno = EINVAL;
01863                 return NULL;
01864         }
01865 }

const apol_vector_t* apol_domain_trans_result_get_setexec_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.

Parameters:
dtr Domain transition result node.
Returns:
Vector of qpol_avrule_t relative to the policy originally used to generate the results.

Definition at line 1867 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::setexec_rules.

Referenced by dta_invalid().

01868 {
01869         if (dtr) {
01870                 return dtr->setexec_rules;
01871         } else {
01872                 errno = EINVAL;
01873                 return NULL;
01874         }
01875 }

const apol_vector_t* apol_domain_trans_result_get_type_trans_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.

Parameters:
dtr Domain transition result node.
Returns:
Vector of qpol_terule_t relative to the policy originally used to generate the results.

Definition at line 1877 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::type_trans_rules.

Referenced by dta_invalid().

01878 {
01879         if (dtr) {
01880                 return dtr->type_trans_rules;
01881         } else {
01882                 errno = EINVAL;
01883                 return NULL;
01884         }
01885 }

int apol_domain_trans_result_is_trans_valid const apol_domain_trans_result_t dtr  ) 
 

Determine if the transition in an apol_domain_trans_result node is valid.

Parameters:
dtr Domain transition result node.
Returns:
0 if invalid and non-zero if valid. If dtr is NULL, returns 0.

Definition at line 1887 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, and apol_domain_trans_result::valid.

Referenced by dta_invalid().

01888 {
01889         if (dtr) {
01890                 return dtr->valid;
01891         } else {
01892                 errno = EINVAL;
01893                 return 0;
01894         }
01895 }

const apol_vector_t* apol_domain_trans_result_get_access_rules 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 should not call apol_vector_destroy() upon the returned vector. This vector is only populated if access criteria were specified in the analysis.

Parameters:
dtr Domain transition result node.
Returns:
Pointer to a vector of rules relative to the policy originally used to generate the results.

Definition at line 1897 of file domain-trans-analysis.c.

References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, and apol_vector_t.

Referenced by dta_forward_access().

01898 {
01899         if (dtr) {
01900                 return dtr->access_rules;
01901         } else {
01902                 errno = EINVAL;
01903                 return NULL;
01904         }
01905 }

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
 

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.

Parameters:
policy The policy containing the domain transition table to consult. Must be non-NULL.
start_dom The starting domain of the transition. May be NULL.
ep_type The entrypoint of the transition. May be NULL.
end_dom The ending domain of the transition. May be NULL.
Returns:
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.

Definition at line 1907 of file domain-trans-analysis.c.

References apol_bst_get_element(), APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_get_qpol(), apol_policy_reset_domain_trans_table(), apol_policy_t, apol_terule_get_by_query(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_default(), apol_terule_query_set_rules(), apol_terule_query_set_source(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, dom_node_t, apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, ep_node_t, find_avrules_in_node(), find_terules_in_node(), QPOL_RULE_TYPE_TRANS, qpol_type_get_name(), and requires_setexec_or_type_trans().

Referenced by inc_dom_trans_run(), and unreachable_doms_run().

01909 {
01910         int missing_rules = 0;
01911 
01912         if (!policy || !policy->domain_trans_table) {
01913                 errno = EINVAL;
01914                 return -1;
01915         }
01916         //reset the table
01917         apol_policy_reset_domain_trans_table(policy);
01918         //find nodes for each type
01919         dom_node_t start_dummy = { start_dom, NULL, NULL, NULL };
01920         dom_node_t *start_node = NULL;
01921         if (start_dom)
01922                 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&start_dummy, NULL, (void **)&start_node);
01923         ep_node_t ep_dummy = { ep_type, NULL, NULL };
01924         ep_node_t *ep_node = NULL;
01925         if (ep_type)
01926                 apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&ep_dummy, NULL, (void **)&ep_node);
01927         dom_node_t end_dummy = { end_dom, NULL, NULL, NULL };
01928         dom_node_t *end_node = NULL;
01929         if (end_dom)
01930                 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&end_dummy, NULL, (void **)&end_node);
01931 
01932         bool tt = false, sx = false, ex = false, pt = false, ep = false;
01933 
01934         //find process transition rule
01935         if (start_node && end_dom) {
01936                 apol_vector_t *v = find_avrules_in_node(start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, end_dom);
01937                 if (apol_vector_get_size(v))
01938                         pt = true;
01939                 apol_vector_destroy(&v);
01940         }
01941         //find execute rule
01942         if (start_dom && ep_node) {
01943                 apol_vector_t *v = find_avrules_in_node(ep_node, APOL_DOMAIN_TRANS_RULE_EXEC, start_dom);
01944                 if (apol_vector_get_size(v))
01945                         ex = true;
01946                 apol_vector_destroy(&v);
01947         }
01948         //find entrypoint rules
01949         if (end_node && ep_type) {
01950                 apol_vector_t *v = find_avrules_in_node(end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, ep_type);
01951                 if (apol_vector_get_size(v))
01952                         ep = true;
01953                 apol_vector_destroy(&v);
01954         }
01955         if (requires_setexec_or_type_trans(policy)) {
01956                 //find setexec rule
01957                 if (start_node)
01958                         if (apol_vector_get_size(start_node->setexec_rules))
01959                                 sx = true;
01960                 //find type_transition rule
01961                 if (ep_node && start_dom && end_dom) {
01962                         apol_vector_t *v = find_terules_in_node(ep_node, start_dom, end_dom);
01963                         if (apol_vector_get_size(v)) {
01964                                 tt = true;
01965                         }
01966                         apol_vector_destroy(&v);
01967                 }
01968         } else {
01969                 //old policy version - pretend these exist
01970                 tt = sx = true;
01971         }
01972 
01973         if (!(pt && ep && ex && (tt || sx))) {
01974                 if (!pt)
01975                         missing_rules |= APOL_DOMAIN_TRANS_RULE_PROC_TRANS;
01976                 if (!ep)
01977                         missing_rules |= APOL_DOMAIN_TRANS_RULE_ENTRYPOINT;
01978                 if (!ex)
01979                         missing_rules |= APOL_DOMAIN_TRANS_RULE_EXEC;
01980                 if (!tt && !sx) {
01981                         missing_rules |= APOL_DOMAIN_TRANS_RULE_SETEXEC;
01982                         //do not report type_transition as missing if there is one for another entrypoint as this would be invalid
01983                         const char *start_name = NULL, *end_name = NULL;
01984                         qpol_type_get_name(apol_policy_get_qpol(policy), start_dom, &start_name);
01985                         qpol_type_get_name(apol_policy_get_qpol(policy), end_dom, &end_name);
01986                         apol_terule_query_t *tq = NULL;
01987                         if (!start_name || !end_name || !(tq = apol_terule_query_create())) {
01988                                 return -1;
01989                         }
01990                         apol_terule_query_set_rules(policy, tq, QPOL_RULE_TYPE_TRANS);
01991                         apol_terule_query_set_source(policy, tq, start_name, 1);
01992                         apol_terule_query_set_default(policy, tq, end_name);
01993                         apol_vector_t *v = NULL;
01994                         if (apol_terule_get_by_query(policy, tq, &v)) {
01995                                 apol_terule_query_destroy(&tq);
01996                                 return -1;
01997                         }
01998                         apol_terule_query_destroy(&tq);
01999                         if (!apol_vector_get_size(v))
02000                                 missing_rules |= APOL_DOMAIN_TRANS_RULE_TYPE_TRANS;
02001                         apol_vector_destroy(&v);
02002                 }
02003         }
02004 
02005         return missing_rules;
02006 }

apol_domain_trans_result_t* apol_domain_trans_result_create_from_domain_trans_result const apol_domain_trans_result_t in  ) 
 

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.

Parameters:
result Pointer to a domain trans result structure to destroy.
Returns:
A clone of the passed in result node, or NULL upon error.

Definition at line 2008 of file domain-trans-analysis.c.

References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, apol_vector_create_from_vector(), domain_trans_result_free(), apol_domain_trans_result::end_type, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, apol_domain_trans_result::proc_trans_rules, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, apol_domain_trans_result::type_trans_rules, and apol_domain_trans_result::valid.

Referenced by apol_domain_trans_analysis_do(), apol_types_relation_clone_domaintrans(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and inc_dom_trans_run().

02009 {
02010         apol_domain_trans_result_t *new_r = NULL;
02011         int retval = -1;
02012         if ((new_r = calloc(1, sizeof(*new_r))) == NULL) {
02013                 goto cleanup;
02014         }
02015         if (result->proc_trans_rules != NULL &&
02016             (new_r->proc_trans_rules = apol_vector_create_from_vector(result->proc_trans_rules, NULL, NULL, NULL)) == NULL) {
02017                 goto cleanup;
02018         }
02019         if (result->ep_rules != NULL
02020             && (new_r->ep_rules = apol_vector_create_from_vector(result->ep_rules, NULL, NULL, NULL)) == NULL) {
02021                 goto cleanup;
02022         }
02023         if (result->exec_rules != NULL
02024             && (new_r->exec_rules = apol_vector_create_from_vector(result->exec_rules, NULL, NULL, NULL)) == NULL) {
02025                 goto cleanup;
02026         }
02027         if (result->setexec_rules != NULL
02028             && (new_r->setexec_rules = apol_vector_create_from_vector(result->setexec_rules, NULL, NULL, NULL)) == NULL) {
02029                 goto cleanup;
02030         }
02031         if (result->type_trans_rules != NULL &&
02032             (new_r->type_trans_rules = apol_vector_create_from_vector(result->type_trans_rules, NULL, NULL, NULL)) == NULL) {
02033                 goto cleanup;
02034         }
02035         if (result->access_rules != NULL
02036             && (new_r->access_rules = apol_vector_create_from_vector(result->access_rules, NULL, NULL, NULL)) == NULL) {
02037                 goto cleanup;
02038         }
02039         new_r->start_type = result->start_type;
02040         new_r->ep_type = result->ep_type;
02041         new_r->end_type = result->end_type;
02042         new_r->valid = result->valid;
02043         retval = 0;
02044       cleanup:
02045         if (retval != 0) {
02046                 domain_trans_result_free(new_r);
02047                 return NULL;
02048         }
02049         return new_r;
02050 }

void domain_trans_result_free void *  dtr  ) 
 

Free all memory associated with a domain transition result, including the pointer itself.

This function does nothing if the result is NULL.

Parameters:
dtr Pointer to a domain transition result structure to free.

Definition at line 2054 of file domain-trans-analysis.c.

References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, apol_vector_destroy(), apol_domain_trans_result::ep_rules, apol_domain_trans_result::exec_rules, apol_domain_trans_result::proc_trans_rules, apol_domain_trans_result::setexec_rules, and apol_domain_trans_result::type_trans_rules.

Referenced by apol_domain_trans_analysis_do(), apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_destroy(), apol_types_relation_clone_domaintrans(), and apol_types_relation_domain().

02055 {
02056         apol_domain_trans_result_t *res = (apol_domain_trans_result_t *) dtr;
02057 
02058         if (!res)
02059                 return;
02060 
02061         apol_vector_destroy(&res->proc_trans_rules);
02062         apol_vector_destroy(&res->ep_rules);
02063         apol_vector_destroy(&res->exec_rules);
02064         apol_vector_destroy(&res->setexec_rules);
02065         apol_vector_destroy(&res->type_trans_rules);
02066         apol_vector_destroy(&res->access_rules);
02067         free(res);
02068 }

void apol_domain_trans_result_destroy apol_domain_trans_result_t **  res  ) 
 

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. 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.

Parameters:
res Reference pointer to a result to destroy.

Definition at line 2070 of file domain-trans-analysis.c.

References apol_domain_trans_result_t, and domain_trans_result_free().

Referenced by domain_trans_result_create(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and dtr_free_wrap().

02071 {
02072         if (!res || !(*res))
02073                 return;
02074         domain_trans_result_free((void *)*res);
02075         *res = NULL;
02076 }