avrule-query.c File Reference


Detailed Description

Provides a way for setools to make queries about access vector rules within a policy.

The caller obtains a query object, fills in its parameters, and then runs the query; it obtains a vector of results. Searches are conjunctive -- all fields of the search query must match for a datum to be added to the results query.

Author:
Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Copyright (C) 2006-2007 Tresys Technology, LLC

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Definition in file avrule-query.c.

#include "policy-query-internal.h"
#include <apol/bst.h>
#include <qpol/policy_extend.h>
#include <errno.h>
#include <string.h>

Go to the source code of this file.


Classes

struct  apol_avrule_query

Functions

int rule_select (const apol_policy_t *p, apol_vector_t *v, uint32_t rule_type, unsigned int flags, const apol_vector_t *source_list, const apol_vector_t *target_list, const apol_vector_t *class_list, const apol_vector_t *perm_list, const char *bool_name)
 Common semantic rule selection routine used in get*rule_by_query.
int apol_avrule_get_by_query (const apol_policy_t *p, const apol_avrule_query_t *a, apol_vector_t **v)
 Execute a query against all access vector rules within the policy.
int apol_syn_avrule_get_by_query (const apol_policy_t *p, const apol_avrule_query_t *a, apol_vector_t **v)
 Execute a query against all syntactic access vector rules within the policy.
apol_avrule_query_tapol_avrule_query_create (void)
 Allocate and return a new avrule query structure.
void apol_avrule_query_destroy (apol_avrule_query_t **a)
 Deallocate all memory associated with the referenced avrule query, and then set it to NULL.
int apol_avrule_query_set_rules (const apol_policy_t *p __attribute__((unused)), apol_avrule_query_t *a, unsigned int rules)
int apol_avrule_query_set_source (const apol_policy_t *p, apol_avrule_query_t *a, const char *symbol, int is_indirect)
 Set an avrule query to return rules whose source symbol matches symbol.
int apol_avrule_query_set_source_component (const apol_policy_t *p, apol_avrule_query_t *a, unsigned int component)
 Set an avrule query to return rules whose source symbol is matched as a type or an attribute.
int apol_avrule_query_set_target (const apol_policy_t *p, apol_avrule_query_t *a, const char *symbol, int is_indirect)
 Set an avrule query to return rules whose target symbol matches symbol.
int apol_avrule_query_set_target_component (const apol_policy_t *p, apol_avrule_query_t *a, unsigned int component)
 Set an avrule query to return rules whose target symbol is matched as a type or an attribute.
int apol_avrule_query_append_class (const apol_policy_t *p, apol_avrule_query_t *a, const char *obj_class)
 Set an avrule query to return rules with this object (non-common) class.
int apol_avrule_query_append_perm (const apol_policy_t *p, apol_avrule_query_t *a, const char *perm)
 Set an avrule query to return rules with this permission.
int apol_avrule_query_set_bool (const apol_policy_t *p, apol_avrule_query_t *a, const char *bool_name)
 Set an avrule query to return rules that are in conditionals and whose conditional uses a particular boolean variable.
int apol_avrule_query_set_enabled (const apol_policy_t *p, apol_avrule_query_t *a, int is_enabled)
 Set an avrule query to search only enabled rules within the policy.
int apol_avrule_query_set_all_perms (const apol_policy_t *p, apol_avrule_query_t *a, int match_all)
 Normally, if more than one permission are added to the query then all returned rules will have at least one of those permissions.
int apol_avrule_query_set_source_any (const apol_policy_t *p, apol_avrule_query_t *a, int is_any)
 Set an avrule query to treat the source symbol as any.
int apol_avrule_query_set_regex (const apol_policy_t *p, apol_avrule_query_t *a, int is_regex)
 Set an avrule query to use regular expression searching for source and target types/attributes.
int apol_syn_avrule_comp (const void *a, const void *b, void *data)
 Comparison function for two syntactic avrules.
apol_vector_tapol_avrule_to_syn_avrules (const apol_policy_t *p, const qpol_avrule_t *rule, const apol_vector_t *perms)
 Given a single avrule, return a newly allocated vector of qpol_syn_avrule_t pointers (relative to the given policy) which comprise that rule.
apol_vector_tapol_avrule_list_to_syn_avrules (const apol_policy_t *p, const apol_vector_t *rules, const apol_vector_t *perms)
 Given a vector of avrules (qpol_avrule_t pointers), return a newly allocated vector of qpol_syn_avrule_t pointers (relative to the given policy) which comprise all of those rules.
char * apol_avrule_render (const apol_policy_t *policy, const qpol_avrule_t *rule)
 Render an avrule to a string.
char * apol_syn_avrule_render (const apol_policy_t *policy, const qpol_syn_avrule_t *rule)
 Render a syntactic avrule to a string.

Function Documentation

int rule_select const apol_policy_t p,
apol_vector_t v,
uint32_t  rule_type,
unsigned int  flags,
const apol_vector_t source_list,
const apol_vector_t target_list,
const apol_vector_t class_list,
const apol_vector_t perm_list,
const char *  bool_name
[static]
 

Common semantic rule selection routine used in get*rule_by_query.

Parameters:
p Policy to search.
v Vector of rules to populate (of type qpol_avrule_t).
rule_type Mask of rules to search.
flags Query options as specified by the apol_avrule_query.
source_list If non-NULL, list of types to use as source. If NULL, accept all types.
target_list If non-NULL, list of types to use as target. If NULL, accept all types.
class_list If non-NULL, list of classes to use. If NULL, accept all classes.
perm_list If non-NULL, list of permisions to use. If NULL, accept all permissions.
bool_name If non-NULL, find conditional rules affected by this boolean. If NULL, all rules will be considered (including unconditional rules).
Returns:
0 on success and < 0 on failure.

Definition at line 62 of file avrule-query.c.

References apol_compare_cond_expr(), apol_compare_iter(), apol_policy_t, apol_regex_destroy(), apol_vector_append(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_t, ERR, apol_policy::p, qpol_avrule_get_cond(), qpol_avrule_get_is_enabled(), qpol_avrule_get_object_class(), qpol_avrule_get_perm_iter(), qpol_avrule_get_source_type(), qpol_avrule_get_target_type(), qpol_avrule_t, qpol_class_t, qpol_cond_t, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_policy_get_avrule_iter(), and qpol_type_t.

00065 {
00066         qpol_iterator_t *iter = NULL, *perm_iter = NULL;
00067         const int only_enabled = flags & APOL_QUERY_ONLY_ENABLED;
00068         const int is_regex = flags & APOL_QUERY_REGEX;
00069         const int source_as_any = flags & APOL_QUERY_SOURCE_AS_ANY;
00070         size_t num_perms_to_match = 1;
00071         int retv = -1;
00072         regex_t *bool_regex = NULL;
00073 
00074         if ((flags & APOL_QUERY_MATCH_ALL_PERMS) && perm_list != NULL) {
00075                 num_perms_to_match = apol_vector_get_size(perm_list);
00076         }
00077         if (qpol_policy_get_avrule_iter(p->p, rule_type, &iter) < 0) {
00078                 goto cleanup;
00079         }
00080         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00081                 qpol_avrule_t *rule;
00082                 uint32_t is_enabled;
00083                 const qpol_cond_t *cond = NULL;
00084                 int match_source = 0, match_target = 0, match_bool = 0;
00085                 size_t match_perm = 0, i;
00086                 if (qpol_iterator_get_item(iter, (void **)&rule) < 0) {
00087                         goto cleanup;
00088                 }
00089 
00090                 if (qpol_avrule_get_is_enabled(p->p, rule, &is_enabled) < 0) {
00091                         goto cleanup;
00092                 }
00093                 if (!is_enabled && only_enabled) {
00094                         continue;
00095                 }
00096 
00097                 if (bool_name != NULL) {
00098                         if (qpol_avrule_get_cond(p->p, rule, &cond) < 0) {
00099                                 goto cleanup;
00100                         }
00101                         if (cond == NULL) {
00102                                 continue;       /* skip unconditional rule */
00103                         }
00104                         match_bool = apol_compare_cond_expr(p, cond, bool_name, is_regex, &bool_regex);
00105                         if (match_bool < 0) {
00106                                 goto cleanup;
00107                         } else if (match_bool == 0) {
00108                                 continue;
00109                         }
00110                 }
00111 
00112                 if (source_list == NULL) {
00113                         match_source = 1;
00114                 } else {
00115                         const qpol_type_t *source_type;
00116                         if (qpol_avrule_get_source_type(p->p, rule, &source_type) < 0) {
00117                                 goto cleanup;
00118                         }
00119                         if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) {
00120                                 match_source = 1;
00121                         }
00122                 }
00123 
00124                 /* if source did not match, but treating source symbol
00125                  * as any field, then delay rejecting this rule until
00126                  * the target has been checked */
00127                 if (!source_as_any && !match_source) {
00128                         continue;
00129                 }
00130 
00131                 if (target_list == NULL || (source_as_any && match_source)) {
00132                         match_target = 1;
00133                 } else {
00134                         const qpol_type_t *target_type;
00135                         if (qpol_avrule_get_target_type(p->p, rule, &target_type) < 0) {
00136                                 goto cleanup;
00137                         }
00138                         if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) {
00139                                 match_target = 1;
00140                         }
00141                 }
00142 
00143                 if (!match_target) {
00144                         continue;
00145                 }
00146 
00147                 if (class_list != NULL) {
00148                         const qpol_class_t *obj_class;
00149                         if (qpol_avrule_get_object_class(p->p, rule, &obj_class) < 0) {
00150                                 goto cleanup;
00151                         }
00152                         if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) {
00153                                 continue;
00154                         }
00155                 }
00156 
00157                 if (perm_list != NULL) {
00158                         for (i = 0; i < apol_vector_get_size(perm_list) && match_perm < num_perms_to_match; i++) {
00159                                 char *perm = (char *)apol_vector_get_element(perm_list, i);
00160                                 if (qpol_avrule_get_perm_iter(p->p, rule, &perm_iter) < 0) {
00161                                         goto cleanup;
00162                                 }
00163                                 int match = apol_compare_iter(p, perm_iter, perm, 0, NULL, 1);
00164                                 if (match < 0) {
00165                                         goto cleanup;
00166                                 } else if (match > 0) {
00167                                         match_perm++;
00168                                 }
00169                                 qpol_iterator_destroy(&perm_iter);
00170                         }
00171                 } else {
00172                         match_perm = num_perms_to_match;
00173                 }
00174                 if (match_perm < num_perms_to_match) {
00175                         continue;
00176                 }
00177 
00178                 if (apol_vector_append(v, rule)) {
00179                         ERR(p, "%s", strerror(ENOMEM));
00180                         goto cleanup;
00181                 }
00182         }
00183 
00184         retv = 0;
00185       cleanup:
00186         apol_regex_destroy(&bool_regex);
00187         qpol_iterator_destroy(&iter);
00188         qpol_iterator_destroy(&perm_iter);
00189         return retv;
00190 }

int apol_avrule_get_by_query const apol_policy_t p,
const apol_avrule_query_t a,
apol_vector_t **  v
 

Execute a query against all access vector rules within the policy.

Parameters:
p Policy within which to look up avrules.
a Structure containing parameters for query. If this is NULL then return all avrules.
v Reference to a vector of qpol_avrule_t. The vector will be allocated by this function. The caller must call apol_vector_destroy() afterwards. This will be set to NULL upon no results or upon error.
Returns:
0 on success (including none found), negative on error.

Definition at line 192 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_get_qpol(), apol_policy_t, apol_query_create_candidate_class_list(), apol_query_create_candidate_type_list(), APOL_QUERY_SOURCE_ATTRIBUTE, APOL_QUERY_SOURCE_INDIRECT, APOL_QUERY_SOURCE_TYPE, APOL_QUERY_TARGET_ATTRIBUTE, APOL_QUERY_TARGET_INDIRECT, APOL_QUERY_TARGET_TYPE, apol_vector_create(), apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, apol_avrule_query::bool_name, apol_avrule_query::classes, ERR, apol_avrule_query::flags, apol_avrule_query::perms, QPOL_CAP_NEVERALLOW, qpol_policy_has_capability(), QPOL_RULE_ALLOW, QPOL_RULE_AUDITALLOW, rule_select(), apol_avrule_query::rules, apol_avrule_query::source, and apol_avrule_query::target.

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), apol_types_relation_allows(), apol_types_relation_create_access_pools(), attribs_wo_rules_run(), avrule_default(), find_domains_run(), find_file_types_run(), find_net_domains_run(), imp_range_trans_run(), inc_mount_run(), inc_net_access_run(), perform_av_query(), policy_view_find_terules_runner(), relabel_analysis_object(), relabel_analysis_subject(), spurious_audit_run(), and types_wo_allow_run().

00193 {
00194         apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *perm_list = NULL;
00195         int retval = -1, source_as_any = 0, is_regex = 0;
00196         char *bool_name = NULL;
00197         *v = NULL;
00198         unsigned int flags = 0;
00199 
00200         uint32_t rule_type = QPOL_RULE_ALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT;
00201         if (qpol_policy_has_capability(apol_policy_get_qpol(p), QPOL_CAP_NEVERALLOW)) {
00202                 rule_type |= QPOL_RULE_NEVERALLOW;
00203         }
00204         if (a != NULL) {
00205                 if (a->rules != 0) {
00206                         rule_type &= a->rules;
00207                 }
00208                 flags = a->flags;
00209                 is_regex = a->flags & APOL_QUERY_REGEX;
00210                 bool_name = a->bool_name;
00211                 if (a->source != NULL &&
00212                     (source_list =
00213                      apol_query_create_candidate_type_list(p, a->source, is_regex,
00214                                                            a->flags & APOL_QUERY_SOURCE_INDIRECT,
00215                                                            ((a->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
00216                                                             APOL_QUERY_SOURCE_TYPE))) == NULL) {
00217                         goto cleanup;
00218                 }
00219                 if ((a->flags & APOL_QUERY_SOURCE_AS_ANY) && a->source != NULL) {
00220                         target_list = source_list;
00221                         source_as_any = 1;
00222                 } else if (a->target != NULL &&
00223                            (target_list =
00224                             apol_query_create_candidate_type_list(p, a->target, is_regex,
00225                                                                   a->flags & APOL_QUERY_TARGET_INDIRECT,
00226                                                                   ((a->
00227                                                                     flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE))
00228                                                                    / APOL_QUERY_TARGET_TYPE))) == NULL) {
00229                         goto cleanup;
00230                 }
00231                 if (a->classes != NULL &&
00232                     apol_vector_get_size(a->classes) > 0 &&
00233                     (class_list = apol_query_create_candidate_class_list(p, a->classes)) == NULL) {
00234                         goto cleanup;
00235                 }
00236                 if (a->perms != NULL && apol_vector_get_size(a->perms) > 0) {
00237                         perm_list = a->perms;
00238                 }
00239         }
00240 
00241         if ((*v = apol_vector_create(NULL)) == NULL) {
00242                 ERR(p, "%s", strerror(errno));
00243                 goto cleanup;
00244         }
00245 
00246         if (rule_select(p, *v, rule_type, flags, source_list, target_list, class_list, perm_list, bool_name)) {
00247                 goto cleanup;
00248         }
00249 
00250         retval = 0;
00251       cleanup:
00252         if (retval != 0) {
00253                 apol_vector_destroy(v);
00254         }
00255         apol_vector_destroy(&source_list);
00256         if (!source_as_any) {
00257                 apol_vector_destroy(&target_list);
00258         }
00259         apol_vector_destroy(&class_list);
00260         /* don't destroy perm_list - it points to query's permission list */
00261         return retval;
00262 }

int apol_syn_avrule_get_by_query const apol_policy_t p,
const apol_avrule_query_t a,
apol_vector_t **  v
 

Execute a query against all syntactic access vector rules within the policy.

If the policy has line numbers, then the returned list

Parameters:
p Policy within which to look up avrules. The policy must be capable of having syntactic rules.
a Structure containing parameters for query. If this is NULL then return all avrules.
v Reference to a vector of qpol_syn_avrule_t. The vector will be allocated by this function. The caller must call apol_vector_destroy() afterwards. This will be set to NULL upon no results or upon error.
Returns:
0 on success (including none found), negative on error.

Definition at line 264 of file avrule-query.c.

References apol_avrule_list_to_syn_avrules(), apol_avrule_query_t, apol_policy_get_qpol(), apol_policy_t, apol_query_create_candidate_class_list(), apol_query_create_candidate_syn_type_list(), apol_query_create_candidate_type_list(), APOL_QUERY_SOURCE_ATTRIBUTE, APOL_QUERY_SOURCE_INDIRECT, APOL_QUERY_SOURCE_TYPE, APOL_QUERY_TARGET_ATTRIBUTE, APOL_QUERY_TARGET_INDIRECT, APOL_QUERY_TARGET_TYPE, apol_query_type_set_uses_types_directly(), apol_regex_destroy(), apol_vector_create(), apol_vector_create_from_vector(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_remove(), apol_vector_t, apol_avrule_query::bool_name, apol_avrule_query::classes, ERR, apol_avrule_query::flags, apol_policy::p, apol_avrule_query::perms, QPOL_CAP_SYN_RULES, qpol_iterator_destroy(), qpol_iterator_t, qpol_policy_has_capability(), QPOL_RULE_ALLOW, QPOL_RULE_AUDITALLOW, QPOL_RULE_NEVERALLOW, qpol_syn_avrule_get_is_target_self(), qpol_syn_avrule_get_source_type_set(), qpol_syn_avrule_get_target_type_set(), qpol_syn_avrule_t, qpol_type_get_isattr(), qpol_type_set_t, qpol_type_t, rule_select(), apol_avrule_query::rules, apol_avrule_query::source, and apol_avrule_query::target.

Referenced by avrule_basic_syn(), perform_av_query(), and policy_view_find_terules_runner().

00265 {
00266         qpol_iterator_t *iter = NULL, *perm_iter = NULL;
00267         apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *perm_list = NULL, *syn_v = NULL;
00268         apol_vector_t *target_types_list = NULL;
00269         int retval = -1, source_as_any = 0, is_regex = 0;
00270         char *bool_name = NULL;
00271         regex_t *bool_regex = NULL;
00272         *v = NULL;
00273         size_t i;
00274         unsigned int flags = 0;
00275 
00276         if (!p || !qpol_policy_has_capability(apol_policy_get_qpol(p), QPOL_CAP_SYN_RULES)) {
00277                 ERR(p, "%s", strerror(EINVAL));
00278                 goto cleanup;
00279         }
00280 
00281         uint32_t rule_type = QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT;
00282         if (a != NULL) {
00283                 if (a->rules != 0) {
00284                         rule_type &= a->rules;
00285                 }
00286                 flags = a->flags;
00287                 is_regex = a->flags & APOL_QUERY_REGEX;
00288                 bool_name = a->bool_name;
00289                 if (a->source != NULL &&
00290                     (source_list =
00291                      apol_query_create_candidate_syn_type_list(p, a->source, is_regex,
00292                                                                a->flags & APOL_QUERY_SOURCE_INDIRECT,
00293                                                                ((a->flags & (APOL_QUERY_SOURCE_TYPE |
00294                                                                              APOL_QUERY_SOURCE_ATTRIBUTE)) /
00295                                                                 APOL_QUERY_SOURCE_TYPE))) == NULL) {
00296                         goto cleanup;
00297                 }
00298                 if ((a->flags & APOL_QUERY_SOURCE_AS_ANY) && a->source != NULL) {
00299                         target_list = source_list;
00300                         source_as_any = 1;
00301                 } else if (a->target != NULL &&
00302                            (target_list =
00303                             apol_query_create_candidate_syn_type_list(p, a->target, is_regex,
00304                                                                       a->flags & APOL_QUERY_TARGET_INDIRECT,
00305                                                                       ((a->flags & (APOL_QUERY_TARGET_TYPE |
00306                                                                                     APOL_QUERY_TARGET_ATTRIBUTE))
00307                                                                        / APOL_QUERY_TARGET_TYPE))) == NULL) {
00308                         goto cleanup;
00309                 }
00310                 if (a->classes != NULL &&
00311                     apol_vector_get_size(a->classes) > 0 &&
00312                     (class_list = apol_query_create_candidate_class_list(p, a->classes)) == NULL) {
00313                         goto cleanup;
00314                 }
00315                 if (a->perms != NULL && apol_vector_get_size(a->perms) > 0) {
00316                         perm_list = a->perms;
00317                 }
00318         }
00319 
00320         if ((*v = apol_vector_create(NULL)) == NULL) {
00321                 ERR(p, "%s", strerror(errno));
00322                 goto cleanup;
00323         }
00324 
00325         if (rule_select(p, *v, rule_type, flags, source_list, target_list, class_list, perm_list, bool_name)) {
00326                 goto cleanup;
00327         }
00328 
00329         syn_v = apol_avrule_list_to_syn_avrules(p, *v, perm_list);
00330         if (!syn_v) {
00331                 goto cleanup;
00332         }
00333         apol_vector_destroy(v);
00334         *v = syn_v;
00335         syn_v = NULL;
00336 
00337         /* if both fields are indirect skip post filtering type sets */
00338         if ((a->flags & APOL_QUERY_SOURCE_INDIRECT) && (a->flags & (APOL_QUERY_TARGET_INDIRECT | APOL_QUERY_SOURCE_AS_ANY))) {
00339                 retval = 0;
00340                 goto cleanup;
00341         }
00342         /* if not searching by source or target we are done */
00343         if (!source_list && !target_list) {
00344                 retval = 0;
00345                 goto cleanup;
00346         }
00347 
00348         if (source_list && !(a->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00349                 apol_vector_destroy(&source_list);
00350                 source_list =
00351                         apol_query_create_candidate_type_list(p, a->source, is_regex, 0,
00352                                                               ((a->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
00353                                                                APOL_QUERY_SOURCE_TYPE));
00354                 if (!source_list)
00355                         goto cleanup;
00356         }
00357         if (target_list && (source_as_any || !(a->flags & APOL_QUERY_TARGET_INDIRECT))) {
00358                 if (source_as_any) {
00359                         target_list = source_list;
00360                 } else {
00361                         apol_vector_destroy(&target_list);
00362                         target_list =
00363                                 apol_query_create_candidate_type_list(p, a->target, is_regex, 0,
00364                                                                       ((a->flags & (APOL_QUERY_SOURCE_TYPE |
00365                                                                                     APOL_QUERY_SOURCE_ATTRIBUTE)) /
00366                                                                        APOL_QUERY_SOURCE_TYPE));
00367                         if (!target_list)
00368                                 goto cleanup;
00369                 }
00370         }
00371         if (target_list) {
00372                 target_types_list = apol_vector_create_from_vector(target_list, NULL, NULL, NULL);
00373                 if (!target_types_list) {
00374                         ERR(p, "%s", strerror(errno));
00375                         goto cleanup;
00376                 }
00377                 qpol_type_t *type = NULL;
00378                 for (i = 0; i < apol_vector_get_size(target_types_list); i++) {
00379                         type = apol_vector_get_element(target_types_list, i);
00380                         unsigned char isattr = 0;
00381                         qpol_type_get_isattr(p->p, type, &isattr);
00382                         if (isattr) {
00383                                 apol_vector_remove(target_types_list, i);
00384                                 i--;
00385                         }
00386                 }
00387         }
00388         for (i = 0; i < apol_vector_get_size(*v); i++) {
00389                 qpol_syn_avrule_t *srule = apol_vector_get_element(*v, i);
00390                 const qpol_type_set_t *stypes = NULL, *ttypes = NULL;
00391                 int uses_source = 0, uses_target = 0;
00392                 uint32_t is_self = 0;
00393                 qpol_syn_avrule_get_source_type_set(p->p, srule, &stypes);
00394                 qpol_syn_avrule_get_target_type_set(p->p, srule, &ttypes);
00395                 qpol_syn_avrule_get_is_target_self(p->p, srule, &is_self);
00396                 if (source_list && !(a->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00397                         uses_source = apol_query_type_set_uses_types_directly(p, stypes, source_list);
00398                         if (uses_source < 0)
00399                                 goto cleanup;
00400                 } else if (source_list && a->flags & APOL_QUERY_SOURCE_INDIRECT) {
00401                         uses_source = 1;
00402                 } else if (!source_list) {
00403                         uses_source = 1;
00404                 }
00405 
00406                 if (target_list
00407                     && !((a->flags & APOL_QUERY_TARGET_INDIRECT) || (source_as_any && a->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00408                         uses_target = apol_query_type_set_uses_types_directly(p, ttypes, target_list);
00409                         if (uses_target < 0)
00410                                 goto cleanup;
00411                         if (is_self) {
00412                                 uses_target |= apol_query_type_set_uses_types_directly(p, stypes, target_types_list);
00413                                 if (uses_target < 0)
00414                                         goto cleanup;
00415                         }
00416                 } else if (target_list && ((a->flags & APOL_QUERY_TARGET_INDIRECT)
00417                                            || (source_as_any && a->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00418                         uses_target = 1;
00419                 } else if (!target_list) {
00420                         uses_target = 1;
00421                 }
00422 
00423                 if (!((uses_source && uses_target) || (source_as_any && (uses_source || uses_target)))) {
00424                         apol_vector_remove(*v, i);
00425                         i--;
00426                 }
00427         }
00428 
00429         retval = 0;
00430       cleanup:
00431         if (retval != 0) {
00432                 apol_vector_destroy(v);
00433         }
00434         apol_vector_destroy(&syn_v);
00435         apol_vector_destroy(&source_list);
00436         apol_vector_destroy(&target_types_list);
00437         if (!source_as_any) {
00438                 apol_vector_destroy(&target_list);
00439         }
00440         apol_vector_destroy(&class_list);
00441         /* don't destroy perm_list - it points to query's permission list */
00442         apol_regex_destroy(&bool_regex);
00443         qpol_iterator_destroy(&iter);
00444         qpol_iterator_destroy(&perm_iter);
00445         return retval;
00446 }

apol_avrule_query_t* apol_avrule_query_create void   ) 
 

Allocate and return a new avrule query structure.

All fields are initialized, such that running this blank query results in returning all avrules within the policy. The caller must call apol_avrule_query_destroy() upon the return value afterwards.

Returns:
An initialized avrule query structure, or NULL upon error.

Definition at line 448 of file avrule-query.c.

References apol_avrule_query_t, APOL_QUERY_SOURCE_ATTRIBUTE, APOL_QUERY_SOURCE_TYPE, APOL_QUERY_TARGET_TYPE, apol_avrule_query::flags, and apol_avrule_query::rules.

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), apol_types_relation_allows(), apol_types_relation_create_access_pools(), attribs_wo_rules_run(), avrule_basic_syn(), avrule_default(), find_domains_run(), find_file_types_run(), find_net_domains_run(), imp_range_trans_run(), inc_mount_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_object(), relabel_analysis_subject(), spurious_audit_run(), and types_wo_allow_run().

00449 {
00450         apol_avrule_query_t *a = calloc(1, sizeof(apol_avrule_query_t));
00451         if (a != NULL) {
00452                 a->rules = ~0U;
00453                 a->flags =
00454                         (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE |
00455                          APOL_QUERY_TARGET_ATTRIBUTE);
00456         }
00457         return a;
00458 }

void apol_avrule_query_destroy apol_avrule_query_t **  a  ) 
 

Deallocate all memory associated with the referenced avrule query, and then set it to NULL.

This function does nothing if the query is already NULL.

Parameters:
a Reference to a avrule query structure to destroy.

Definition at line 460 of file avrule-query.c.

References apol_avrule_query_t, and apol_vector_destroy().

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), apol_types_relation_allows(), apol_types_relation_create_access_pools(), attribs_wo_rules_run(), avrule_basic_syn(), avrule_default(), find_domains_run(), find_file_types_run(), find_net_domains_run(), imp_range_trans_run(), inc_mount_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_object(), relabel_analysis_subject(), spurious_audit_run(), and types_wo_allow_run().

00461 {
00462         if (*a != NULL) {
00463                 free((*a)->source);
00464                 free((*a)->target);
00465                 free((*a)->bool_name);
00466                 apol_vector_destroy(&(*a)->classes);
00467                 apol_vector_destroy(&(*a)->perms);
00468                 free(*a);
00469                 *a = NULL;
00470         }
00471 }

int apol_avrule_query_set_rules const apol_policy_t *p   __attribute__((unused)),
apol_avrule_query_t a,
unsigned int  rules
 

Definition at line 473 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, and apol_avrule_query::rules.

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), apol_types_relation_allows(), apol_types_relation_create_access_pools(), avrule_basic_syn(), find_net_domains_run(), imp_range_trans_run(), inc_mount_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_object(), relabel_analysis_subject(), and spurious_audit_run().

00474 {
00475         if (rules != 0) {
00476                 a->rules = rules;
00477         } else {
00478                 a->rules = ~0U;
00479         }
00480         return 0;
00481 }

int apol_avrule_query_set_source const apol_policy_t p,
apol_avrule_query_t a,
const char *  symbol,
int  is_indirect
 

Set an avrule query to return rules whose source symbol matches symbol.

Symbol may be a type or attribute; if it is an alias then the query will convert it to its primary prior to searching. If is_indirect is non-zero then the search will be done indirectly. If the symbol is a type, then the query matches rules with one of the type's attributes. If the symbol is an attribute, then it matches rule with any of the attribute's types.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
symbol Limit query to rules with this symbol as their source, or NULL to unset this field.
is_indirect If non-zero, perform indirect matching.
Returns:
0 on success, negative on error.

Definition at line 483 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set(), apol_query_set_flag(), APOL_QUERY_SOURCE_INDIRECT, apol_avrule_query::flags, and apol_avrule_query::source.

Referenced by apol_domain_trans_analysis_do(), apol_types_relation_allows(), apol_types_relation_create_access_pools(), attribs_wo_rules_run(), find_domains_run(), find_file_types_run(), imp_range_trans_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_subject(), spurious_audit_run(), and types_wo_allow_run().

00484 {
00485         apol_query_set_flag(p, &a->flags, is_indirect, APOL_QUERY_SOURCE_INDIRECT);
00486         return apol_query_set(p, &a->source, NULL, symbol);
00487 }

int apol_avrule_query_set_source_component const apol_policy_t p,
apol_avrule_query_t a,
unsigned int  component
 

Set an avrule query to return rules whose source symbol is matched as a type or an attribute.

The symbol will match both types and attributes by default.

See also:
apol_avrule_query_set_source() to set the symbol to match.
Parameters:
p Policy handler, to report errors.
a AV rule query to set.
component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component to match.
Returns:
0 on success, negative on error.

Definition at line 489 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set_flag(), APOL_QUERY_SOURCE_ATTRIBUTE, APOL_QUERY_SOURCE_TYPE, APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_SYMBOL_IS_TYPE, ERR, and apol_avrule_query::flags.

Referenced by policy_view_on_find_terules_click().

00490 {
00491         if (!a || !(component & APOL_QUERY_SYMBOL_IS_BOTH)) {
00492                 ERR(p, "%s", strerror(EINVAL));
00493                 errno = EINVAL;
00494                 return -1;
00495         }
00496         apol_query_set_flag(p, &a->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_SOURCE_TYPE);
00497         apol_query_set_flag(p, &a->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_SOURCE_ATTRIBUTE);
00498         return 0;
00499 }

int apol_avrule_query_set_target const apol_policy_t p,
apol_avrule_query_t a,
const char *  symbol,
int  is_indirect
 

Set an avrule query to return rules whose target symbol matches symbol.

Symbol may be a type or attribute; if it is an alias then the query will convert it to its primary prior to searching. If is_indirect is non-zero then the search will be done indirectly. If the symbol is a type, then the query matches rules with one of the type's attributes. If the symbol is an attribute, then it matches rule with any of the attribute's types.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
symbol Limit query to rules with this symbol as their target, or NULL to unset this field.
is_indirect If non-zero, perform indirect matching.
Returns:
0 on success, negative on error.

Definition at line 501 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set(), apol_query_set_flag(), APOL_QUERY_TARGET_INDIRECT, apol_avrule_query::flags, and apol_avrule_query::target.

Referenced by apol_domain_trans_analysis_do(), apol_types_relation_allows(), attribs_wo_rules_run(), imp_range_trans_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_object(), spurious_audit_run(), and types_wo_allow_run().

00502 {
00503         apol_query_set_flag(p, &a->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
00504         return apol_query_set(p, &a->target, NULL, symbol);
00505 }

int apol_avrule_query_set_target_component const apol_policy_t p,
apol_avrule_query_t a,
unsigned int  component
 

Set an avrule query to return rules whose target symbol is matched as a type or an attribute.

The symbol will match both types and attributes by default.

See also:
apol_avrule_query_set_target() to set the symbol to match.
Parameters:
p Policy handler, to report errors.
a AV rule query to set.
component Bit-wise or'ed set of APOL_QUERY_SYMBOL_IS_TYPE and APOL_QUERY_SYMBOL_IS_ATTRIBUTE indicating the type of component to match.
Returns:
0 on success, negative on error.

Definition at line 507 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set_flag(), APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_ATTRIBUTE, APOL_QUERY_TARGET_TYPE, ERR, and apol_avrule_query::flags.

00508 {
00509         if (!a || !(component && APOL_QUERY_SYMBOL_IS_BOTH)) {
00510                 ERR(p, "%s", strerror(EINVAL));
00511                 errno = EINVAL;
00512                 return -1;
00513         }
00514         apol_query_set_flag(p, &a->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_TYPE);
00515         apol_query_set_flag(p, &a->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_TARGET_ATTRIBUTE);
00516         return 0;
00517 }

int apol_avrule_query_append_class const apol_policy_t p,
apol_avrule_query_t a,
const char *  obj_class
 

Set an avrule query to return rules with this object (non-common) class.

If more than one class are appended to the query, the rule's class must be one of those appended. (I.e., the rule's class must be a member of the query's classes.) Pass a NULL to clear all classes. Note that this performs straight string comparison, ignoring the regex flag.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
obj_class Name of object class to add to search set, or NULL to clear all classes.
Returns:
0 on success, negative on error.

Definition at line 519 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_avrule_query::classes, and ERR.

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), avrule_basic_syn(), find_file_types_run(), imp_range_trans_run(), inc_mount_run(), inc_net_access_run(), perform_av_query(), policy_view_on_find_terules_click(), relabel_analysis_object(), relabel_analysis_subject(), and spurious_audit_run().

00520 {
00521         char *s = NULL;
00522         if (obj_class == NULL) {
00523                 apol_vector_destroy(&a->classes);
00524         } else if ((s = strdup(obj_class)) == NULL || (a->classes == NULL && (a->classes = apol_vector_create(free)) == NULL)
00525                    || apol_vector_append(a->classes, s) < 0) {
00526                 ERR(p, "%s", strerror(errno));
00527                 free(s);
00528                 return -1;
00529         }
00530         return 0;
00531 }

int apol_avrule_query_append_perm const apol_policy_t p,
apol_avrule_query_t a,
const char *  perm
 

Set an avrule query to return rules with this permission.

By default, if more than one permission are appended to the query, at least one of the rule's permissions must be one of those appended; that is, the intersection of query's and rule's permissions must be non-empty. (This behavior can be changed.) Pass a NULL to clear all permissions. Note that this performs a straight string comparison, ignoring the regex flag.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
perm Name of permission to add to search set, or NULL to clear all permissions.
Returns:
0 on success, negative on error.
See also:
apol_avrule_query_set_all_perms()

Definition at line 533 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), ERR, and apol_avrule_query::perms.

Referenced by apol_domain_trans_analysis_do(), apol_policy_build_domain_trans_table(), find_file_types_run(), imp_range_trans_run(), inc_mount_run(), perform_av_query(), relabel_analysis_object(), and relabel_analysis_subject().

00534 {
00535         char *s;
00536         if (perm == NULL) {
00537                 apol_vector_destroy(&a->perms);
00538         } else if ((s = strdup(perm)) == NULL ||
00539                    (a->perms == NULL && (a->perms = apol_vector_create(free)) == NULL) || apol_vector_append(a->perms, s) < 0) {
00540                 ERR(p, "%s", strerror(ENOMEM));
00541                 return -1;
00542         }
00543         return 0;
00544 }

int apol_avrule_query_set_bool const apol_policy_t p,
apol_avrule_query_t a,
const char *  bool_name
 

Set an avrule query to return rules that are in conditionals and whose conditional uses a particular boolean variable.

Unconditional rules will not be returned.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
bool_name Name of boolean that conditional must contain. If NULL then search all rules.
Returns:
0 on success, negative on error.

Definition at line 546 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set(), and apol_avrule_query::bool_name.

Referenced by perform_av_query().

00547 {
00548         return apol_query_set(p, &a->bool_name, NULL, bool_name);
00549 }

int apol_avrule_query_set_enabled const apol_policy_t p,
apol_avrule_query_t a,
int  is_enabled
 

Set an avrule query to search only enabled rules within the policy.

These include rules that are unconditional and those within enabled conditionals.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
is_enabled Non-zero to search only enabled rules, 0 to search all rules.
Returns:
Always 0.

Definition at line 551 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, APOL_QUERY_ONLY_ENABLED, apol_query_set_flag(), and apol_avrule_query::flags.

00552 {
00553         return apol_query_set_flag(p, &a->flags, is_enabled, APOL_QUERY_ONLY_ENABLED);
00554 }

int apol_avrule_query_set_all_perms const apol_policy_t p,
apol_avrule_query_t a,
int  all_perms
 

Normally, if more than one permission are added to the query then all returned rules will have at least one of those permissions.

If the all_perms flag is set, then returned rules will have all of the given permissions. This flag does nothing if no permissions are given.

Note: If calling apol_syn_avrule_get_by_query(), the returned results may not be what is expected. For a given source-target-class triplet, all of the associated permissions are unioned together prior to executing the avrule query. Although a given syntactic AV rule might not have all of the matched permissions, the union of the rules' permissions will them. For example, consider these two allow rules:

allow A B : C p1;
 *allow A B : C p2;

If the avrule query has both permissions p1 and p2 and the all_perms flag is set, then both of these syntactic rules will be returned by apol_syn_avrule_get_by_query().

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
all_perms Non-zero to match all permissions, zero to match any permission.
Returns:
Always 0.
See also:
apol_avrule_query_append_perm()

Definition at line 556 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, APOL_QUERY_MATCH_ALL_PERMS, apol_query_set_flag(), and apol_avrule_query::flags.

00557 {
00558         return apol_query_set_flag(p, &a->flags, match_all, APOL_QUERY_MATCH_ALL_PERMS);
00559 }

int apol_avrule_query_set_source_any const apol_policy_t p,
apol_avrule_query_t a,
int  is_any
 

Set an avrule query to treat the source symbol as any.

That is, use the same symbol for either source or target of a rule. This flag does nothing if the source symbol is not set.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
is_any Non-zero to use source symbol for any field, 0 to keep source as only source.
Returns:
Always 0.

Definition at line 561 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set_flag(), APOL_QUERY_SOURCE_AS_ANY, and apol_avrule_query::flags.

00562 {
00563         return apol_query_set_flag(p, &a->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
00564 }

int apol_avrule_query_set_regex const apol_policy_t p,
apol_avrule_query_t a,
int  is_regex
 

Set an avrule query to use regular expression searching for source and target types/attributes.

Strings will be treated as regexes instead of literals. Matching will occur against the type name or any of its aliases.

Parameters:
p Policy handler, to report errors.
a AV rule query to set.
is_regex Non-zero to enable regex searching, 0 to disable.
Returns:
Always 0.

Definition at line 566 of file avrule-query.c.

References apol_avrule_query_t, apol_policy_t, apol_query_set_regex(), and apol_avrule_query::flags.

Referenced by perform_av_query(), and policy_view_on_find_terules_click().

00567 {
00568         return apol_query_set_regex(p, &a->flags, is_regex);
00569 }

int apol_syn_avrule_comp const void *  a,
const void *  b,
void *  data
[static]
 

Comparison function for two syntactic avrules.

Will return -1 if a's line number is before b's, 1 if b is greater.

Definition at line 575 of file avrule-query.c.

References apol_policy_t, apol_policy::p, qpol_syn_avrule_get_lineno(), and qpol_syn_avrule_t.

Referenced by apol_avrule_list_to_syn_avrules(), and apol_avrule_to_syn_avrules().

00576 {
00577         qpol_syn_avrule_t *r1 = (qpol_syn_avrule_t *) a;
00578         qpol_syn_avrule_t *r2 = (qpol_syn_avrule_t *) b;
00579         apol_policy_t *p = (apol_policy_t *) data;
00580         unsigned long num1, num2;
00581         if (qpol_syn_avrule_get_lineno(p->p, r1, &num1) < 0 || qpol_syn_avrule_get_lineno(p->p, r2, &num2) < 0) {
00582                 return 0;
00583         }
00584         if (num1 != num2) {
00585                 return (int)num1 - (int)num2;
00586         }
00587         return (int)((char *)r1 - (char *)r2);
00588 }

apol_vector_t* apol_avrule_to_syn_avrules const apol_policy_t p,
const qpol_avrule_t rule,
const apol_vector_t perms
 

Given a single avrule, return a newly allocated vector of qpol_syn_avrule_t pointers (relative to the given policy) which comprise that rule.

The vector will be sorted by line numbers if the policy has line numbers. If the given perms vector is non-NULL and non-empty, then only return syntactic rules with at least one permission listed within the perms vector.

Parameters:
p Policy from which to obtain syntactic rules.
rule AV rule to convert.
perms If non-NULL and non-empty, a list of permission strings. Returned syn avrules will have at least one permission in common with this list.
Returns:
A newly allocated vector of syn_avrule_t pointers. The caller is responsible for calling apol_vector_destroy() afterwards.

Definition at line 590 of file avrule-query.c.

References apol_policy_t, apol_str_strcmp(), apol_syn_avrule_comp(), apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, ERR, apol_policy::p, qpol_avrule_get_syn_avrule_iter(), qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_syn_avrule_get_perm_iter(), and qpol_syn_avrule_t.

00591 {
00592         apol_vector_t *v = NULL;
00593         qpol_iterator_t *iter = NULL, *perm_iter = NULL;
00594         qpol_syn_avrule_t *syn_avrule;
00595         char *perm;
00596         size_t i;
00597         int retval = -1, error = 0, found_perm = 0;
00598         if (qpol_avrule_get_syn_avrule_iter(p->p, rule, &iter) < 0) {
00599                 error = errno;
00600                 goto cleanup;
00601         }
00602         if ((v = apol_vector_create(NULL)) == NULL) {
00603                 error = errno;
00604                 ERR(p, "%s", strerror(error));
00605                 goto cleanup;
00606         }
00607         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00608                 if (qpol_iterator_get_item(iter, (void **)&syn_avrule) < 0) {
00609                         error = errno;
00610                         ERR(p, "%s", strerror(error));
00611                         goto cleanup;
00612                 }
00613                 found_perm = 0;
00614                 if (perms != NULL && apol_vector_get_size(perms) > 0) {
00615                         if (qpol_syn_avrule_get_perm_iter(p->p, syn_avrule, &perm_iter) < 0) {
00616                                 goto cleanup;
00617                         }
00618                         for (; !qpol_iterator_end(perm_iter); qpol_iterator_next(perm_iter)) {
00619                                 if (qpol_iterator_get_item(perm_iter, (void **)&perm) < 0) {
00620                                         error = errno;
00621                                         ERR(p, "%s", strerror(error));
00622                                         goto cleanup;
00623                                 }
00624                                 if (apol_vector_get_index(perms, perm, apol_str_strcmp, NULL, &i) == 0) {
00625                                         found_perm = 1;
00626                                         break;
00627                                 }
00628                         }
00629                 } else {
00630                         found_perm = 1;
00631                 }
00632                 if (found_perm && apol_vector_append(v, syn_avrule) < 0) {
00633                         error = errno;
00634                         ERR(p, "%s", strerror(error));
00635                         goto cleanup;
00636                 }
00637         }
00638         /* explicit cast to void* since vector's arbitrary data is non-const */
00639         apol_vector_sort_uniquify(v, apol_syn_avrule_comp, (void *)p);
00640         retval = 0;
00641       cleanup:
00642         qpol_iterator_destroy(&iter);
00643         qpol_iterator_destroy(&perm_iter);
00644         if (retval != 0) {
00645                 apol_vector_destroy(&v);
00646                 errno = error;
00647                 return NULL;
00648         }
00649         return v;
00650 }

apol_vector_t* apol_avrule_list_to_syn_avrules const apol_policy_t p,
const apol_vector_t rules,
const apol_vector_t perms
 

Given a vector of avrules (qpol_avrule_t pointers), return a newly allocated vector of qpol_syn_avrule_t pointers (relative to the given policy) which comprise all of those rules.

The returned vector will be sorted by line numbers if the policy has line numbers. Also, it will not have any duplicate syntactic rules. If the given perms vector is non-NULL and non-empty, then only return syntactic rules with at least one permission listed within the perms vector.

Parameters:
p Policy from which to obtain syntactic rules.
rules Vector of AV rules to convert.
perms If non-NULL and non-empty, a list of permission strings. Returned syn avrules will have at least one permission in common with this list.
Returns:
A newly allocated vector of syn_avrule_t pointers. The caller is responsible for calling apol_vector_destroy() afterwards.

Definition at line 652 of file avrule-query.c.

References apol_bst_create(), apol_bst_destroy(), apol_bst_get_vector(), apol_bst_insert(), apol_bst_t, apol_policy_t, apol_str_strcmp(), apol_syn_avrule_comp(), apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_t, ERR, apol_policy::p, qpol_avrule_get_syn_avrule_iter(), qpol_avrule_t, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_syn_avrule_get_perm_iter(), and qpol_syn_avrule_t.

Referenced by apol_syn_avrule_get_by_query().

00653 {
00654         apol_bst_t *b = NULL;
00655         qpol_avrule_t *rule;
00656         qpol_iterator_t *iter = NULL;
00657         qpol_syn_avrule_t *syn_avrule;
00658         char *perm;
00659         apol_vector_t *tmp_v = NULL, *v = NULL;
00660         size_t i, x;
00661         int retval = -1, error = 0, found_perm = 0;
00662 
00663         if ((b = apol_bst_create(apol_syn_avrule_comp, NULL)) == NULL) {
00664                 error = errno;
00665                 ERR(p, "%s", strerror(error));
00666                 goto cleanup;
00667         }
00668         for (i = 0; i < apol_vector_get_size(rules); i++) {
00669                 rule = apol_vector_get_element(rules, i);
00670                 if (qpol_avrule_get_syn_avrule_iter(p->p, rule, &iter) < 0) {
00671                         error = errno;
00672                         goto cleanup;
00673                 }
00674                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00675                         if (qpol_iterator_get_item(iter, (void **)&syn_avrule) < 0) {
00676                                 error = errno;
00677                                 ERR(p, "%s", strerror(error));
00678                                 goto cleanup;
00679                         }
00680                         /* explicit cast to void* since bst's arbitrary data is non-const */
00681                         if (apol_bst_insert(b, syn_avrule, (void *)p) < 0) {
00682                                 error = errno;
00683                                 ERR(p, "%s", strerror(error));
00684                                 goto cleanup;
00685                         }
00686                 }
00687                 qpol_iterator_destroy(&iter);
00688         }
00689         if ((tmp_v = apol_bst_get_vector(b, 1)) == NULL) {
00690                 error = errno;
00691                 ERR(p, "%s", strerror(error));
00692                 goto cleanup;
00693         }
00694         if (perms == NULL || apol_vector_get_size(perms) == 0) {
00695                 v = tmp_v;
00696                 tmp_v = NULL;
00697         } else {
00698                 if ((v = apol_vector_create(NULL)) == NULL) {
00699                         error = errno;
00700                         ERR(p, "%s", strerror(error));
00701                         goto cleanup;
00702                 }
00703                 for (i = 0; i < apol_vector_get_size(tmp_v); i++) {
00704                         syn_avrule = apol_vector_get_element(tmp_v, i);
00705                         found_perm = 0;
00706                         if (qpol_syn_avrule_get_perm_iter(p->p, syn_avrule, &iter) < 0) {
00707                                 goto cleanup;
00708                         }
00709                         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00710                                 if (qpol_iterator_get_item(iter, (void **)&perm) < 0) {
00711                                         error = errno;
00712                                         ERR(p, "%s", strerror(error));
00713                                         goto cleanup;
00714                                 }
00715                                 if (apol_vector_get_index(perms, perm, apol_str_strcmp, NULL, &x) == 0) {
00716                                         found_perm = 1;
00717                                         break;
00718                                 }
00719                         }
00720                         qpol_iterator_destroy(&iter);
00721                         if (found_perm && apol_vector_append(v, syn_avrule) < 0) {
00722                                 error = errno;
00723                                 ERR(p, "%s", strerror(error));
00724                                 goto cleanup;
00725                         }
00726                 }
00727         }
00728         retval = 0;
00729       cleanup:
00730         apol_bst_destroy(&b);
00731         qpol_iterator_destroy(&iter);
00732         apol_vector_destroy(&tmp_v);
00733         if (retval != 0) {
00734                 apol_vector_destroy(&v);
00735                 errno = error;
00736                 return NULL;
00737         }
00738         return v;
00739 }

char* apol_avrule_render const apol_policy_t policy,
const qpol_avrule_t rule
 

Render an avrule to a string.

Parameters:
policy Policy handler, to report errors.
rule The rule to render.
Returns:
a newly malloc()'d string representation of the rule, or NULL on failure; if the call fails, errno will be set. The caller is responsible for calling free() on the returned string.

Definition at line 741 of file avrule-query.c.

References apol_policy_t, apol_rule_type_to_str(), apol_str_append(), ERR, apol_policy::p, qpol_avrule_get_object_class(), qpol_avrule_get_perm_iter(), qpol_avrule_get_rule_type(), qpol_avrule_get_source_type(), qpol_avrule_get_target_type(), qpol_class_get_name(), qpol_class_t, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_get_size(), qpol_iterator_next(), qpol_iterator_t, QPOL_RULE_ALLOW, QPOL_RULE_AUDITALLOW, QPOL_RULE_NEVERALLOW, qpol_type_get_name(), and qpol_type_t.

Referenced by dta_forward_access(), find_domains_run(), find_file_types_run(), find_net_domains_run(), inc_mount_run(), policy_view_display_avrule_results(), print_av_results(), and spurious_audit_print().

00742 {
00743         char *tmp = NULL;
00744         const char *rule_type_str, *tmp_name = NULL;
00745         int error = 0;
00746         uint32_t rule_type = 0;
00747         const qpol_type_t *type = NULL;
00748         const qpol_class_t *obj_class = NULL;
00749         qpol_iterator_t *iter = NULL;
00750         size_t tmp_sz = 0, num_perms = 0;
00751 
00752         if (!policy || !rule) {
00753                 ERR(policy, "%s", strerror(EINVAL));
00754                 errno = EINVAL;
00755                 return NULL;
00756         }
00757 
00758         /* rule type */
00759         if (qpol_avrule_get_rule_type(policy->p, rule, &rule_type)) {
00760                 error = errno;
00761                 ERR(policy, "%s", strerror(error));
00762                 errno = error;
00763                 return NULL;
00764         }
00765         if (!(rule_type &= (QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT))) {
00766                 ERR(policy, "%s", "Invalid av rule type");
00767                 errno = EINVAL;
00768                 return NULL;
00769         }
00770         if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00771                 ERR(policy, "%s", "Av rule has multiple rule types?");
00772                 errno = EINVAL;
00773                 return NULL;
00774         }
00775         if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00776                 error = errno;
00777                 ERR(policy, "%s", strerror(error));
00778                 goto err;
00779         }
00780 
00781         /* source type */
00782         if (qpol_avrule_get_source_type(policy->p, rule, &type)) {
00783                 error = errno;
00784                 goto err;
00785         }
00786         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00787                 error = errno;
00788                 goto err;
00789         }
00790         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00791                 error = errno;
00792                 ERR(policy, "%s", strerror(error));
00793                 goto err;
00794         }
00795 
00796         /* target type */
00797         if (qpol_avrule_get_target_type(policy->p, rule, &type)) {
00798                 error = errno;
00799                 goto err;
00800         }
00801         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00802                 error = errno;
00803                 goto err;
00804         }
00805         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " : ")) {
00806                 error = errno;
00807                 ERR(policy, "%s", strerror(error));
00808                 goto err;
00809         }
00810 
00811         /* object class */
00812         if (qpol_avrule_get_object_class(policy->p, rule, &obj_class)) {
00813                 error = errno;
00814                 goto err;
00815         }
00816         if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
00817                 error = errno;
00818                 goto err;
00819         }
00820         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00821                 error = errno;
00822                 ERR(policy, "%s", strerror(error));
00823                 goto err;
00824         }
00825 
00826         /* perms */
00827         if (qpol_avrule_get_perm_iter(policy->p, rule, &iter)) {
00828                 error = errno;
00829                 goto err;
00830         }
00831         if (qpol_iterator_get_size(iter, &num_perms)) {
00832                 error = errno;
00833                 ERR(policy, "%s", strerror(error));
00834                 goto err;
00835         }
00836         if (num_perms > 1) {
00837                 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00838                         error = errno;
00839                         ERR(policy, "%s", strerror(error));
00840                         goto err;
00841                 }
00842         }
00843         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00844                 char *perm_name = NULL;
00845                 if (qpol_iterator_get_item(iter, (void **)&perm_name)) {
00846                         error = errno;
00847                         ERR(policy, "%s", strerror(error));
00848                         goto err;
00849                 }
00850                 if (apol_str_append(&tmp, &tmp_sz, perm_name)) {
00851                         error = error;
00852                         ERR(policy, "%s", strerror(error));
00853                         goto err;
00854                 }
00855                 free(perm_name);
00856                 tmp_name = NULL;
00857                 if (apol_str_append(&tmp, &tmp_sz, " ")) {
00858                         error = error;
00859                         ERR(policy, "%s", strerror(error));
00860                         goto err;
00861                 }
00862         }
00863         if (num_perms > 1) {
00864                 if (apol_str_append(&tmp, &tmp_sz, "}")) {
00865                         error = error;
00866                         ERR(policy, "%s", strerror(error));
00867                         goto err;
00868                 }
00869         }
00870 
00871         if (apol_str_append(&tmp, &tmp_sz, ";")) {
00872                 error = error;
00873                 ERR(policy, "%s", strerror(error));
00874                 goto err;
00875         }
00876 
00877         qpol_iterator_destroy(&iter);
00878         return tmp;
00879 
00880       err:
00881         free(tmp);
00882         qpol_iterator_destroy(&iter);
00883         errno = error;
00884         return NULL;
00885 }

char* apol_syn_avrule_render const apol_policy_t policy,
const qpol_syn_avrule_t rule
 

Render a syntactic avrule to a string.

Parameters:
policy Policy handler to report errors.
rule The rule to render.
Returns:
a newly malloc()'d string representation of the rule, or NULL on failure; if the call fails, errno will be set. The caller is responsible for calling free() on the returned string.

Definition at line 887 of file avrule-query.c.

References apol_policy_t, apol_rule_type_to_str(), apol_str_append(), ERR, apol_policy::p, qpol_class_get_name(), qpol_class_t, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_get_size(), qpol_iterator_next(), qpol_iterator_t, QPOL_RULE_ALLOW, QPOL_RULE_AUDITALLOW, QPOL_RULE_NEVERALLOW, qpol_syn_avrule_get_class_iter(), qpol_syn_avrule_get_is_target_self(), qpol_syn_avrule_get_perm_iter(), qpol_syn_avrule_get_rule_type(), qpol_syn_avrule_get_source_type_set(), qpol_syn_avrule_get_target_type_set(), qpol_type_get_name(), qpol_type_set_get_included_types_iter(), qpol_type_set_get_is_comp(), qpol_type_set_get_is_star(), qpol_type_set_get_subtracted_types_iter(), qpol_type_set_t, and qpol_type_t.

Referenced by policy_view_display_avrule_results(), and print_syn_av_results().

00888 {
00889         char *tmp = NULL;
00890         const char *rule_type_str, *tmp_name = NULL;
00891         int error = 0;
00892         uint32_t rule_type = 0, star = 0, comp = 0, self = 0;
00893         const qpol_type_t *type = NULL;
00894         const qpol_class_t *obj_class = NULL;
00895         qpol_iterator_t *iter = NULL, *iter2 = NULL;
00896         size_t tmp_sz = 0, iter_sz = 0, iter2_sz = 0;
00897         const qpol_type_set_t *set = NULL;
00898 
00899         if (!policy || !rule) {
00900                 ERR(policy, "%s", strerror(EINVAL));
00901                 errno = EINVAL;
00902                 return NULL;
00903         }
00904 
00905         /* rule type */
00906         if (qpol_syn_avrule_get_rule_type(policy->p, rule, &rule_type)) {
00907                 error = errno;
00908                 return NULL;
00909         }
00910         if (!(rule_type &= (QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT))) {
00911                 ERR(policy, "%s", "Invalid av rule type");
00912                 errno = EINVAL;
00913                 return NULL;
00914         }
00915         if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00916                 ERR(policy, "%s", "Av rule has multiple rule types?");
00917                 errno = EINVAL;
00918                 return NULL;
00919         }
00920         if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00921                 error = errno;
00922                 ERR(policy, "%s", strerror(error));
00923                 goto err;
00924         }
00925 
00926         /* source type set */
00927         if (qpol_syn_avrule_get_source_type_set(policy->p, rule, &set)) {
00928                 error = errno;
00929                 goto err;
00930         }
00931         if (qpol_type_set_get_is_star(policy->p, set, &star)) {
00932                 error = errno;
00933                 goto err;
00934         }
00935         if (star) {
00936                 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
00937                         error = errno;
00938                         ERR(policy, "%s", strerror(error));
00939                         goto err;
00940                 }
00941         } else {
00942                 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
00943                         error = errno;
00944                         goto err;
00945                 }
00946                 if (comp) {
00947                         if (apol_str_append(&tmp, &tmp_sz, "~")) {
00948                                 ERR(policy, "%s", strerror(ENOMEM));
00949                                 error = ENOMEM;
00950                                 goto err;
00951                         }
00952                 }
00953                 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
00954                         error = errno;
00955                         goto err;
00956                 }
00957                 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
00958                         error = errno;
00959                         goto err;
00960                 }
00961                 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
00962                         error = errno;
00963                         ERR(policy, "%s", strerror(error));
00964                         goto err;
00965                 }
00966                 if (iter_sz + iter2_sz > 1) {
00967                         if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00968                                 ERR(policy, "%s", strerror(ENOMEM));
00969                                 error = ENOMEM;
00970                                 goto err;
00971                         }
00972                 }
00973                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00974                         if (qpol_iterator_get_item(iter, (void **)&type)) {
00975                                 error = errno;
00976                                 ERR(policy, "%s", strerror(error));
00977                                 goto err;
00978                         }
00979                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00980                                 error = errno;
00981                                 goto err;
00982                         }
00983                         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00984                                 error = errno;
00985                                 ERR(policy, "%s", strerror(error));
00986                                 goto err;
00987                         }
00988                 }
00989                 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
00990                         if (qpol_iterator_get_item(iter2, (void **)&type)) {
00991                                 error = errno;
00992                                 ERR(policy, "%s", strerror(error));
00993                                 goto err;
00994                         }
00995                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00996                                 error = errno;
00997                                 goto err;
00998                         }
00999                         if (apol_str_append(&tmp, &tmp_sz, "-") ||
01000                             apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01001                                 error = errno;
01002                                 ERR(policy, "%s", strerror(error));
01003                                 goto err;
01004                         }
01005                 }
01006                 qpol_iterator_destroy(&iter);
01007                 qpol_iterator_destroy(&iter2);
01008                 if (iter_sz + iter2_sz > 1) {
01009                         if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01010                                 error = errno;
01011                                 ERR(policy, "%s", strerror(error));
01012                                 goto err;
01013                         }
01014                 }
01015         }
01016 
01017         /* target type set */
01018         if (qpol_syn_avrule_get_target_type_set(policy->p, rule, &set)) {
01019                 error = errno;
01020                 goto err;
01021         }
01022         if (qpol_type_set_get_is_star(policy->p, set, &star)) {
01023                 error = errno;
01024                 goto err;
01025         }
01026         if (star) {
01027                 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
01028                         error = errno;
01029                         ERR(policy, "%s", strerror(error));
01030                         goto err;
01031                 }
01032         } else {
01033                 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
01034                         error = errno;
01035                         goto err;
01036                 }
01037                 if (comp) {
01038                         if (apol_str_append(&tmp, &tmp_sz, "~")) {
01039                                 error = errno;
01040                                 ERR(policy, "%s", strerror(error));
01041                                 goto err;
01042                         }
01043                 }
01044                 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
01045                         error = errno;
01046                         goto err;
01047                 }
01048                 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
01049                         error = errno;
01050                         goto err;
01051                 }
01052                 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
01053                         error = errno;
01054                         ERR(policy, "%s", strerror(error));
01055                         goto err;
01056                 }
01057                 if (iter_sz + iter2_sz > 1) {
01058                         if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
01059                                 error = errno;
01060                                 ERR(policy, "%s", strerror(error));
01061                                 goto err;
01062                         }
01063                 }
01064                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
01065                         if (qpol_iterator_get_item(iter, (void **)&type)) {
01066                                 error = errno;
01067                                 ERR(policy, "%s", strerror(error));
01068                                 goto err;
01069                         }
01070                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
01071                                 error = errno;
01072                                 goto err;
01073                         }
01074                         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01075                                 error = errno;
01076                                 ERR(policy, "%s", strerror(error));
01077                                 goto err;
01078                         }
01079                 }
01080                 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
01081                         if (qpol_iterator_get_item(iter2, (void **)&type)) {
01082                                 error = errno;
01083                                 ERR(policy, "%s", strerror(error));
01084                                 goto err;
01085                         }
01086                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
01087                                 error = errno;
01088                                 goto err;
01089                         }
01090                         if (apol_str_append(&tmp, &tmp_sz, "-") ||
01091                             apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01092                                 error = errno;
01093                                 ERR(policy, "%s", strerror(error));
01094                                 goto err;
01095                         }
01096                 }
01097                 qpol_iterator_destroy(&iter);
01098                 qpol_iterator_destroy(&iter2);
01099                 if (qpol_syn_avrule_get_is_target_self(policy->p, rule, &self)) {
01100                         error = errno;
01101                         goto err;
01102                 }
01103                 if (self) {
01104                         if (apol_str_append(&tmp, &tmp_sz, "self ")) {
01105                                 error = errno;
01106                                 ERR(policy, "%s", strerror(error));
01107                                 goto err;
01108                         }
01109                 }
01110                 if (iter_sz + iter2_sz > 1) {
01111                         if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01112                                 error = errno;
01113                                 ERR(policy, "%s", strerror(error));
01114                                 goto err;
01115                         }
01116                 }
01117         }
01118 
01119         if (apol_str_append(&tmp, &tmp_sz, ": ")) {
01120                 error = errno;
01121                 ERR(policy, "%s", strerror(error));
01122                 goto err;
01123         }
01124 
01125         /* object classes */
01126         if (qpol_syn_avrule_get_class_iter(policy->p, rule, &iter)) {
01127                 error = errno;
01128                 goto err;
01129         }
01130         if (qpol_iterator_get_size(iter, &iter_sz)) {
01131                 error = errno;
01132                 ERR(policy, "%s", strerror(error));
01133                 goto err;
01134         }
01135         if (iter_sz > 1) {
01136                 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
01137                         error = errno;
01138                         ERR(policy, "%s", strerror(error));
01139                         goto err;
01140                 }
01141         }
01142         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
01143                 if (qpol_iterator_get_item(iter, (void **)&obj_class)) {
01144                         error = errno;
01145                         ERR(policy, "%s", strerror(error));
01146                         goto err;
01147                 }
01148                 if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
01149                         error = errno;
01150                         goto err;
01151                 }
01152                 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01153                         error = errno;
01154                         ERR(policy, "%s", strerror(error));
01155                         goto err;
01156                 }
01157         }
01158         qpol_iterator_destroy(&iter);
01159         if (iter_sz > 1) {
01160                 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01161                         error = errno;
01162                         ERR(policy, "%s", strerror(error));
01163                         goto err;
01164                 }
01165         }
01166 
01167         /* permissions */
01168         if (qpol_syn_avrule_get_perm_iter(policy->p, rule, &iter)) {
01169                 error = errno;
01170                 goto err;
01171         }
01172         if (qpol_iterator_get_size(iter, &iter_sz)) {
01173                 error = errno;
01174                 ERR(policy, "%s", strerror(error));
01175                 goto err;
01176         }
01177         if (iter_sz > 1) {
01178                 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
01179                         error = errno;
01180                         ERR(policy, "%s", strerror(error));
01181                         goto err;
01182                 }
01183         }
01184         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
01185                 if (qpol_iterator_get_item(iter, (void **)&tmp_name)) {
01186                         error = errno;
01187                         ERR(policy, "%s", strerror(error));
01188                         goto err;
01189                 }
01190                 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01191                         error = errno;
01192                         ERR(policy, "%s", strerror(error));
01193                         goto err;
01194                 }
01195         }
01196         qpol_iterator_destroy(&iter);
01197         if (iter_sz > 1) {
01198                 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01199                         error = errno;
01200                         ERR(policy, "%s", strerror(error));
01201                         goto err;
01202                 }
01203         }
01204 
01205         if (apol_str_append(&tmp, &tmp_sz, ";")) {
01206                 error = errno;
01207                 ERR(policy, "%s", strerror(error));
01208                 goto err;
01209         }
01210 
01211         return tmp;
01212 
01213       err:
01214         free(tmp);
01215         qpol_iterator_destroy(&iter);
01216         qpol_iterator_destroy(&iter2);
01217         errno = error;
01218         return NULL;
01219 }