terule-query.c File Reference


Detailed Description

Provides a way for setools to make queries about type enforcement 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 terule-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_terule_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 *default_list, const char *bool_name)
 Common semantic rule selection routine used in get*rule_by_query.
int apol_terule_get_by_query (const apol_policy_t *p, const apol_terule_query_t *t, apol_vector_t **v)
 Execute a query against all type enforcement rules within the policy.
int apol_syn_terule_get_by_query (const apol_policy_t *p, const apol_terule_query_t *t, apol_vector_t **v)
 Execute a query against all syntactic type enforcement rules within the policy.
apol_terule_query_tapol_terule_query_create (void)
 Allocate and return a new terule query structure.
void apol_terule_query_destroy (apol_terule_query_t **t)
 Deallocate all memory associated with the referenced terule query, and then set it to NULL.
int apol_terule_query_set_rules (const apol_policy_t *p __attribute__((unused)), apol_terule_query_t *t, unsigned int rules)
int apol_terule_query_set_source (const apol_policy_t *p, apol_terule_query_t *t, const char *symbol, int is_indirect)
 Set a terule query to return rules whose source symbol matches symbol.
int apol_terule_query_set_source_component (const apol_policy_t *p, apol_terule_query_t *t, unsigned int component)
 Set an terule query to return rules whose source symbol is matched as a type or an attribute.
int apol_terule_query_set_target (const apol_policy_t *p, apol_terule_query_t *t, const char *symbol, int is_indirect)
 Set a terule query to return rules whose target symbol matches symbol.
int apol_terule_query_set_target_component (const apol_policy_t *p, apol_terule_query_t *t, unsigned int component)
 Set an terule query to return rules whose target symbol is matched as a type or an attribute.
int apol_terule_query_set_default (const apol_policy_t *p, apol_terule_query_t *t, const char *symbol)
 Set a terule query to return rules with this default type.
int apol_terule_query_append_class (const apol_policy_t *p, apol_terule_query_t *t, const char *obj_class)
 Set at terule query to return rules with this object (non-common) class.
int apol_terule_query_set_bool (const apol_policy_t *p, apol_terule_query_t *t, const char *bool_name)
 Set a terule query to return rules that are in conditionals and whose conditional uses a particular boolean variable.
int apol_terule_query_set_enabled (const apol_policy_t *p, apol_terule_query_t *t, int is_enabled)
 Set a terule query to search only enabled rules within the policy.
int apol_terule_query_set_source_any (const apol_policy_t *p, apol_terule_query_t *t, int is_any)
 Set a terule query to treat the source symbol as any.
int apol_terule_query_set_regex (const apol_policy_t *p, apol_terule_query_t *t, int is_regex)
 Set a terule query to use regular expression searching for source and target types/attributes and default type.
int apol_syn_terule_comp (const void *a, const void *b, void *data)
 Comparison function for two syntactic terules.
apol_vector_tapol_terule_to_syn_terules (const apol_policy_t *p, const qpol_terule_t *rule)
 Given a single terule, return a newly allocated vector of qpol_syn_terule_t pointers (relative to the given policy) which comprise that rule.
apol_vector_tapol_terule_list_to_syn_terules (const apol_policy_t *p, const apol_vector_t *rules)
 Given a vector of terules (qpol_terule_t pointers), return a newly allocated vector of qpol_syn_terule_t pointers (relative to the given policy) which comprise all of those rules.
char * apol_terule_render (const apol_policy_t *policy, const qpol_terule_t *rule)
 Render a terule to a string.
char * apol_syn_terule_render (const apol_policy_t *policy, const qpol_syn_terule_t *rule)
 Render a syntactic terule 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 default_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_terule_t).
rule_type Mask of rules to search.
flags Query options as specified by the apol_terule_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.
default_list If non-NULL, list of types to use as default. If NULL, accept all types.
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 terule-query.c.

References apol_compare_cond_expr(), apol_policy_t, apol_regex_destroy(), apol_vector_append(), apol_vector_get_index(), apol_vector_t, ERR, apol_policy::p, 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_terule_iter(), qpol_terule_get_cond(), qpol_terule_get_default_type(), qpol_terule_get_is_enabled(), qpol_terule_get_object_class(), qpol_terule_get_source_type(), qpol_terule_get_target_type(), qpol_terule_t, and qpol_type_t.

Referenced by apol_avrule_get_by_query(), apol_syn_avrule_get_by_query(), apol_syn_terule_get_by_query(), and apol_terule_get_by_query().

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

int apol_terule_get_by_query const apol_policy_t p,
const apol_terule_query_t t,
apol_vector_t **  v
 

Execute a query against all type enforcement rules within the policy.

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

Definition at line 188 of file terule-query.c.

References 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_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_ATTRIBUTE, APOL_QUERY_TARGET_INDIRECT, APOL_QUERY_TARGET_TYPE, apol_terule_query_t, apol_vector_create(), apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, apol_terule_query::bool_name, apol_terule_query::classes, apol_terule_query::default_type, ERR, apol_terule_query::flags, QPOL_RULE_TYPE_MEMBER, QPOL_RULE_TYPE_TRANS, rule_select(), apol_terule_query::rules, apol_terule_query::source, and apol_terule_query::target.

Referenced by apol_domain_trans_table_verify_trans(), apol_policy_build_domain_trans_table(), apol_types_relation_types(), attribs_wo_rules_run(), find_domains_run(), find_file_types_run(), and perform_te_query().

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

int apol_syn_terule_get_by_query const apol_policy_t p,
const apol_terule_query_t t,
apol_vector_t **  v
 

Execute a query against all syntactic type enforcement rules within the policy.

If the policy has line numbers, then the returned list will be sorted increasingly by line number.

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

Definition at line 262 of file terule-query.c.

References 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_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_ATTRIBUTE, APOL_QUERY_TARGET_INDIRECT, APOL_QUERY_TARGET_TYPE, apol_query_type_set_uses_types_directly(), apol_terule_list_to_syn_terules(), apol_terule_query_t, apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_remove(), apol_vector_t, apol_terule_query::bool_name, apol_terule_query::classes, apol_terule_query::default_type, ERR, apol_terule_query::flags, apol_policy::p, QPOL_CAP_SYN_RULES, qpol_policy_has_capability(), QPOL_RULE_TYPE_MEMBER, QPOL_RULE_TYPE_TRANS, qpol_syn_terule_get_default_type(), qpol_syn_terule_get_source_type_set(), qpol_syn_terule_get_target_type_set(), qpol_syn_terule_t, qpol_type_set_t, qpol_type_t, rule_select(), apol_terule_query::rules, apol_terule_query::source, and apol_terule_query::target.

Referenced by perform_te_query(), and terule_basic_syn().

00263 {
00264         apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL, *syn_v = NULL;
00265         int retval = -1, source_as_any = 0, is_regex = 0;
00266         char *bool_name = NULL;
00267         *v = NULL;
00268         size_t i;
00269         unsigned int flags = 0;
00270 
00271         if (!p || !qpol_policy_has_capability(apol_policy_get_qpol(p), QPOL_CAP_SYN_RULES)) {
00272                 ERR(p, "%s", strerror(EINVAL));
00273                 goto cleanup;
00274         }
00275 
00276         uint32_t rule_type = QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_MEMBER | QPOL_RULE_TYPE_CHANGE;
00277         if (t != NULL) {
00278                 if (t->rules != 0) {
00279                         rule_type &= t->rules;
00280                 }
00281                 flags = t->flags;
00282                 is_regex = t->flags & APOL_QUERY_REGEX;
00283                 bool_name = t->bool_name;
00284                 if (t->source != NULL &&
00285                     (source_list =
00286                      apol_query_create_candidate_syn_type_list(p, t->source, is_regex,
00287                                                                t->flags & APOL_QUERY_SOURCE_INDIRECT,
00288                                                                ((t->flags & (APOL_QUERY_SOURCE_TYPE |
00289                                                                              APOL_QUERY_SOURCE_ATTRIBUTE)) /
00290                                                                 APOL_QUERY_SOURCE_TYPE))) == NULL) {
00291                         goto cleanup;
00292                 }
00293                 if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) {
00294                         default_list = target_list = source_list;
00295                         source_as_any = 1;
00296                 } else {
00297                         if (t->target != NULL &&
00298                             (target_list =
00299                              apol_query_create_candidate_syn_type_list(p, t->target, is_regex,
00300                                                                        t->flags & APOL_QUERY_TARGET_INDIRECT,
00301                                                                        ((t->flags & (APOL_QUERY_TARGET_TYPE |
00302                                                                                      APOL_QUERY_TARGET_ATTRIBUTE))
00303                                                                         / APOL_QUERY_TARGET_TYPE))) == NULL) {
00304                                 goto cleanup;
00305                         }
00306                         if (t->default_type != NULL &&
00307                             (default_list =
00308                              apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0,
00309                                                                    APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) {
00310                                 goto cleanup;
00311                         }
00312                 }
00313                 if (t->classes != NULL &&
00314                     apol_vector_get_size(t->classes) > 0 &&
00315                     (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) {
00316                         goto cleanup;
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, default_list, bool_name)) {
00326                 goto cleanup;
00327         }
00328 
00329         syn_v = apol_terule_list_to_syn_terules(p, *v);
00330         if (!syn_v) {
00331                 goto cleanup;
00332         }
00333         apol_vector_destroy(v);
00334         *v = syn_v;
00335         syn_v = NULL;
00336 
00337         /* if source and target are indirect skip post filtering type sets */
00338         if ((t->flags & APOL_QUERY_SOURCE_INDIRECT) && (t->flags & (APOL_QUERY_TARGET_INDIRECT | APOL_QUERY_SOURCE_AS_ANY))) {
00339                 retval = 0;
00340                 goto cleanup;
00341         }
00342         /* if not searching by source, target, or default we are done */
00343         if (!source_list && !target_list && !default_list) {
00344                 retval = 0;
00345                 goto cleanup;
00346         }
00347 
00348         if (source_list && !(t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00349                 apol_vector_destroy(&source_list);
00350                 source_list =
00351                         apol_query_create_candidate_type_list(p, t->source, is_regex, 0,
00352                                                               ((t->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 || !(t->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, t->target, is_regex, 0,
00364                                                                       ((t->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 (source_as_any) {
00372                 default_list = source_list;
00373         }
00374 
00375         for (i = 0; i < apol_vector_get_size(*v); i++) {
00376                 qpol_syn_terule_t *srule = apol_vector_get_element(*v, i);
00377                 const qpol_type_set_t *stypes = NULL, *ttypes = NULL;
00378                 const qpol_type_t *dflt = NULL;
00379                 size_t j;
00380                 int uses_source = 0, uses_target = 0, uses_default = 0;
00381                 qpol_syn_terule_get_source_type_set(p->p, srule, &stypes);
00382                 qpol_syn_terule_get_target_type_set(p->p, srule, &ttypes);
00383                 if (source_list && !(t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00384                         uses_source = apol_query_type_set_uses_types_directly(p, stypes, source_list);
00385                         if (uses_source < 0)
00386                                 goto cleanup;
00387                 } else if (source_list && (t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00388                         uses_source = 1;
00389                 } else if (!source_list) {
00390                         uses_source = 1;
00391                 }
00392 
00393                 if (target_list
00394                     && !(t->flags & APOL_QUERY_TARGET_INDIRECT || (source_as_any && t->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00395                         uses_target = apol_query_type_set_uses_types_directly(p, ttypes, target_list);
00396                         if (uses_target < 0)
00397                                 goto cleanup;
00398                 } else if (target_list
00399                            && (t->flags & APOL_QUERY_TARGET_INDIRECT || (source_as_any && t->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00400                         uses_target = 1;
00401                 } else if (!target_list) {
00402                         uses_target = 1;
00403                 }
00404 
00405                 if (default_list) {
00406                         qpol_syn_terule_get_default_type(p->p, srule, &dflt);
00407                         if (!apol_vector_get_index(default_list, (void *)dflt, NULL, NULL, &j))
00408                                 uses_default = 1;
00409                 } else if (!default_list) {
00410                         uses_default = 1;
00411                 }
00412 
00413                 if (!((uses_source && uses_target && uses_default)
00414                       || (source_as_any && (uses_source || uses_target || uses_default)))) {
00415                         apol_vector_remove(*v, i);
00416                         i--;
00417                 }
00418         }
00419 
00420         retval = 0;
00421       cleanup:
00422         if (retval != 0) {
00423                 apol_vector_destroy(v);
00424         }
00425         apol_vector_destroy(&syn_v);
00426         apol_vector_destroy(&source_list);
00427         if (!source_as_any) {
00428                 apol_vector_destroy(&target_list);
00429                 apol_vector_destroy(&default_list);
00430         }
00431         apol_vector_destroy(&class_list);
00432         return retval;
00433 }

apol_terule_query_t* apol_terule_query_create void   ) 
 

Allocate and return a new terule query structure.

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

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

Definition at line 435 of file terule-query.c.

References APOL_QUERY_SOURCE_ATTRIBUTE, APOL_QUERY_SOURCE_TYPE, APOL_QUERY_TARGET_TYPE, apol_terule_query_t, apol_terule_query::flags, and apol_terule_query::rules.

Referenced by apol_domain_trans_table_verify_trans(), apol_policy_build_domain_trans_table(), apol_types_relation_types(), attribs_wo_rules_run(), find_domains_run(), find_file_types_run(), perform_te_query(), and terule_basic_syn().

00436 {
00437         apol_terule_query_t *t = calloc(1, sizeof(apol_terule_query_t));
00438         if (t != NULL) {
00439                 t->rules = ~0U;
00440                 t->flags =
00441                         (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE |
00442                          APOL_QUERY_TARGET_ATTRIBUTE);
00443         }
00444         return t;
00445 }

void apol_terule_query_destroy apol_terule_query_t **  t  ) 
 

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

This function does nothing if the query is already NULL.

Parameters:
t Reference to a terule query structure to destroy.

Definition at line 447 of file terule-query.c.

References apol_terule_query_t, and apol_vector_destroy().

Referenced by apol_domain_trans_table_verify_trans(), apol_policy_build_domain_trans_table(), apol_types_relation_types(), attribs_wo_rules_run(), find_domains_run(), find_file_types_run(), perform_te_query(), and terule_basic_syn().

00448 {
00449         if (*t != NULL) {
00450                 free((*t)->source);
00451                 free((*t)->target);
00452                 free((*t)->default_type);
00453                 free((*t)->bool_name);
00454                 apol_vector_destroy(&(*t)->classes);
00455                 free(*t);
00456                 *t = NULL;
00457         }
00458 }

int apol_terule_query_set_rules const apol_policy_t *p   __attribute__((unused)),
apol_terule_query_t t,
unsigned int  rules
 

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

References apol_policy_t, apol_terule_query_t, and apol_terule_query::rules.

Referenced by apol_domain_trans_table_verify_trans(), apol_policy_build_domain_trans_table(), apol_types_relation_types(), perform_te_query(), and terule_basic_syn().

00461 {
00462         if (rules != 0) {
00463                 t->rules = rules;
00464         } else {
00465                 t->rules = ~0U;
00466         }
00467         return 0;
00468 }

int apol_terule_query_set_source const apol_policy_t p,
apol_terule_query_t t,
const char *  symbol,
int  is_indirect
 

Set a terule query to return rules whose source symbol matches symbol.

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

Parameters:
p Policy handler, to report errors.
t TE 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 470 of file terule-query.c.

References apol_policy_t, apol_query_set(), apol_query_set_flag(), APOL_QUERY_SOURCE_INDIRECT, apol_terule_query_t, apol_terule_query::flags, and apol_terule_query::source.

Referenced by apol_domain_trans_table_verify_trans(), apol_types_relation_types(), attribs_wo_rules_run(), and perform_te_query().

00471 {
00472         apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_SOURCE_INDIRECT);
00473         return apol_query_set(p, &t->source, NULL, symbol);
00474 }

int apol_terule_query_set_source_component const apol_policy_t p,
apol_terule_query_t t,
unsigned int  component
 

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

The symbol will match both types and attributes by default.

See also:
apol_avrule_query_set_source() to set the symbol to match.
Parameters:
p Policy handler, to report errors.
t TE 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 476 of file terule-query.c.

References 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, apol_terule_query_t, ERR, and apol_terule_query::flags.

00477 {
00478         if (!t || !(component & APOL_QUERY_SYMBOL_IS_BOTH)) {
00479                 ERR(p, "%s", strerror(EINVAL));
00480                 errno = EINVAL;
00481                 return -1;
00482         }
00483         apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_SOURCE_TYPE);
00484         apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_SOURCE_ATTRIBUTE);
00485         return 0;
00486 }

int apol_terule_query_set_target const apol_policy_t p,
apol_terule_query_t t,
const char *  symbol,
int  is_indirect
 

Set a terule query to return rules whose target symbol matches symbol.

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

Parameters:
p Policy handler, to report errors.
t TE 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 488 of file terule-query.c.

References apol_policy_t, apol_query_set(), apol_query_set_flag(), APOL_QUERY_TARGET_INDIRECT, apol_terule_query_t, apol_terule_query::flags, and apol_terule_query::target.

Referenced by attribs_wo_rules_run(), and perform_te_query().

00489 {
00490         apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
00491         return apol_query_set(p, &t->target, NULL, symbol);
00492 }

int apol_terule_query_set_target_component const apol_policy_t p,
apol_terule_query_t t,
unsigned int  component
 

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

The symbol will match both types and attributes by default.

See also:
apol_avrule_query_set_source() to set the symbol to match.
Parameters:
p Policy handler, to report errors.
t TE 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 494 of file terule-query.c.

References 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, apol_terule_query_t, ERR, and apol_terule_query::flags.

00495 {
00496         if (!t || !(component & APOL_QUERY_SYMBOL_IS_BOTH)) {
00497                 ERR(p, "%s", strerror(EINVAL));
00498                 errno = EINVAL;
00499                 return -1;
00500         }
00501         apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_TYPE);
00502         apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_TARGET_ATTRIBUTE);
00503         return 0;
00504 }

int apol_terule_query_set_default const apol_policy_t p,
apol_terule_query_t t,
const char *  type
 

Set a terule query to return rules with this default type.

The symbol may be a type or any of its aliases; it may not be an attribute.

Parameters:
p Policy handler, to report errors.
t TE rule query to set.
type Name of default type to search.
Returns:
0 on success, negative on error.

Definition at line 506 of file terule-query.c.

References apol_policy_t, apol_query_set(), apol_terule_query_t, and apol_terule_query::default_type.

Referenced by apol_domain_trans_table_verify_trans(), find_domains_run(), and find_file_types_run().

00507 {
00508         return apol_query_set(p, &t->default_type, NULL, symbol);
00509 }

int apol_terule_query_append_class const apol_policy_t p,
apol_terule_query_t t,
const char *  obj_class
 

Set at terule query to return rules with this object (non-common) class.

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

Parameters:
p Policy handler, to report errors.
t TE rule query to set.
obj_class Name of object class to add to search set.
Returns:
0 on success, negative on error.

Definition at line 511 of file terule-query.c.

References apol_policy_t, apol_terule_query_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_terule_query::classes, and ERR.

Referenced by apol_policy_build_domain_trans_table(), find_domains_run(), perform_te_query(), and terule_basic_syn().

00512 {
00513         char *s = NULL;
00514         if (obj_class == NULL) {
00515                 apol_vector_destroy(&t->classes);
00516         } else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL)
00517                    || apol_vector_append(t->classes, s) < 0) {
00518                 ERR(p, "%s", strerror(errno));
00519                 free(s);
00520                 return -1;
00521         }
00522         return 0;
00523 }

int apol_terule_query_set_bool const apol_policy_t p,
apol_terule_query_t t,
const char *  bool_name
 

Set a terule query to 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.
t TE 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 525 of file terule-query.c.

References apol_policy_t, apol_query_set(), apol_terule_query_t, and apol_terule_query::bool_name.

Referenced by perform_te_query().

00526 {
00527         return apol_query_set(p, &t->bool_name, NULL, bool_name);
00528 }

int apol_terule_query_set_enabled const apol_policy_t p,
apol_terule_query_t t,
int  is_enabled
 

Set a terule 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.
t TE rule query to set.
is_enabled Non-zero to search only enabled rules, 0 to search all rules.
Returns:
Always 0.

Definition at line 530 of file terule-query.c.

References apol_policy_t, APOL_QUERY_ONLY_ENABLED, apol_query_set_flag(), apol_terule_query_t, and apol_terule_query::flags.

00531 {
00532         return apol_query_set_flag(p, &t->flags, is_enabled, APOL_QUERY_ONLY_ENABLED);
00533 }

int apol_terule_query_set_source_any const apol_policy_t p,
apol_terule_query_t t,
int  is_any
 

Set a terule query to treat the source symbol as any.

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

Parameters:
p Policy handler, to report errors.
t TE 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 535 of file terule-query.c.

References apol_policy_t, apol_query_set_flag(), APOL_QUERY_SOURCE_AS_ANY, apol_terule_query_t, and apol_terule_query::flags.

00536 {
00537         return apol_query_set_flag(p, &t->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
00538 }

int apol_terule_query_set_regex const apol_policy_t p,
apol_terule_query_t t,
int  is_regex
 

Set a terule query to use regular expression searching for source and target types/attributes and default type.

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

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

Definition at line 540 of file terule-query.c.

References apol_policy_t, apol_query_set_regex(), apol_terule_query_t, and apol_terule_query::flags.

Referenced by perform_te_query().

00541 {
00542         return apol_query_set_regex(p, &t->flags, is_regex);
00543 }

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

Comparison function for two syntactic terules.

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

Definition at line 549 of file terule-query.c.

References apol_policy_t, apol_policy::p, qpol_syn_terule_get_lineno(), and qpol_syn_terule_t.

Referenced by apol_terule_list_to_syn_terules(), and apol_terule_to_syn_terules().

00550 {
00551         qpol_syn_terule_t *r1 = (qpol_syn_terule_t *) a;
00552         qpol_syn_terule_t *r2 = (qpol_syn_terule_t *) b;
00553         apol_policy_t *p = (apol_policy_t *) data;
00554         unsigned long num1, num2;
00555         if (qpol_syn_terule_get_lineno(p->p, r1, &num1) < 0 || qpol_syn_terule_get_lineno(p->p, r2, &num2) < 0) {
00556                 return 0;
00557         }
00558         if (num1 != num2) {
00559                 return (int)num1 - (int)num2;
00560         }
00561         return (int)((char *)r1 - (char *)r2);
00562 }

apol_vector_t* apol_terule_to_syn_terules const apol_policy_t p,
const qpol_terule_t rule
 

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

The vector will be sorted by line numbers if the policy has line numbers.

Parameters:
p Policy from which to obtain syntactic rules.
rule TE rule to convert.
Returns:
A newly allocated vector of syn_terule_t pointers. The caller is responsible for calling apol_vector_destroy() afterwards.

Definition at line 564 of file terule-query.c.

References apol_policy_t, apol_syn_terule_comp(), apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_sort_uniquify(), apol_vector_t, ERR, apol_policy::p, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_syn_terule_t, and qpol_terule_get_syn_terule_iter().

00565 {
00566         apol_vector_t *v = NULL;
00567         qpol_iterator_t *iter = NULL;
00568         qpol_syn_terule_t *syn_terule;
00569         int retval = -1, error = 0;
00570         if (qpol_terule_get_syn_terule_iter(p->p, rule, &iter) < 0) {
00571                 error = errno;
00572                 goto cleanup;
00573         }
00574         if ((v = apol_vector_create(NULL)) == NULL) {
00575                 error = errno;
00576                 ERR(p, "%s", strerror(error));
00577                 goto cleanup;
00578         }
00579         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00580                 if (qpol_iterator_get_item(iter, (void **)&syn_terule) < 0) {
00581                         error = errno;
00582                         ERR(p, "%s", strerror(error));
00583                         goto cleanup;
00584                 }
00585                 if (apol_vector_append(v, syn_terule) < 0) {
00586                         error = errno;
00587                         ERR(p, "%s", strerror(error));
00588                         goto cleanup;
00589                 }
00590         }
00591         apol_vector_sort_uniquify(v, apol_syn_terule_comp, (void *)p);
00592         retval = 0;
00593       cleanup:
00594         qpol_iterator_destroy(&iter);
00595         if (retval != 0) {
00596                 apol_vector_destroy(&v);
00597                 errno = error;
00598                 return NULL;
00599         }
00600         return v;
00601 }

apol_vector_t* apol_terule_list_to_syn_terules const apol_policy_t p,
const apol_vector_t rules
 

Given a vector of terules (qpol_terule_t pointers), return a newly allocated vector of qpol_syn_terule_t pointers (relative to the given policy) which comprise all of those rules.

The returned vector will be sorted by line numbers if the policy has line numbers. Also, it will not have any duplicate syntactic rules.

Parameters:
p Policy from which to obtain syntactic rules.
rules Vector of TE rules to convert.
Returns:
A newly allocated vector of syn_terule_t pointers. The caller is responsible for calling apol_vector_destroy() afterwards.

Definition at line 603 of file terule-query.c.

References apol_bst_create(), apol_bst_destroy(), apol_bst_get_vector(), apol_bst_insert(), apol_bst_t, apol_policy_t, apol_syn_terule_comp(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, ERR, apol_policy::p, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_syn_terule_t, qpol_terule_get_syn_terule_iter(), and qpol_terule_t.

Referenced by apol_syn_terule_get_by_query().

00604 {
00605         apol_bst_t *b = NULL;
00606         qpol_terule_t *rule;
00607         qpol_iterator_t *iter = NULL;
00608         qpol_syn_terule_t *syn_terule;
00609         apol_vector_t *v = NULL;
00610         size_t i;
00611         int retval = -1, error = 0;
00612 
00613         if ((b = apol_bst_create(apol_syn_terule_comp, NULL)) == NULL) {
00614                 error = errno;
00615                 ERR(p, "%s", strerror(error));
00616                 goto cleanup;
00617         }
00618         for (i = 0; i < apol_vector_get_size(rules); i++) {
00619                 rule = apol_vector_get_element(rules, i);
00620                 if (qpol_terule_get_syn_terule_iter(p->p, rule, &iter) < 0) {
00621                         error = errno;
00622                         goto cleanup;
00623                 }
00624                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00625                         if (qpol_iterator_get_item(iter, (void **)&syn_terule) < 0) {
00626                                 error = errno;
00627                                 ERR(p, "%s", strerror(error));
00628                                 goto cleanup;
00629                         }
00630                         if (apol_bst_insert(b, syn_terule, (void *)p) < 0) {
00631                                 error = errno;
00632                                 ERR(p, "%s", strerror(error));
00633                                 goto cleanup;
00634                         }
00635                 }
00636                 qpol_iterator_destroy(&iter);
00637         }
00638         if ((v = apol_bst_get_vector(b, 1)) == NULL) {
00639                 error = errno;
00640                 ERR(p, "%s", strerror(error));
00641                 goto cleanup;
00642         }
00643         retval = 0;
00644       cleanup:
00645         apol_bst_destroy(&b);
00646         qpol_iterator_destroy(&iter);
00647         if (retval != 0) {
00648                 errno = error;
00649                 return NULL;
00650         }
00651         return v;
00652 }

char* apol_terule_render const apol_policy_t policy,
const qpol_terule_t rule
 

Render a terule 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 654 of file terule-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_RULE_TYPE_CHANGE, QPOL_RULE_TYPE_TRANS, qpol_terule_get_default_type(), qpol_terule_get_object_class(), qpol_terule_get_rule_type(), qpol_terule_get_source_type(), qpol_terule_get_target_type(), qpol_type_get_name(), and qpol_type_t.

Referenced by find_domains_run(), find_file_types_run(), and print_te_results().

00655 {
00656         char *tmp = NULL;
00657         const char *tmp_name = NULL;
00658         const char *rule_type_str;
00659         int error = 0;
00660         size_t tmp_sz = 0;
00661         uint32_t rule_type = 0;
00662         const qpol_type_t *type = NULL;
00663         const qpol_class_t *obj_class = NULL;
00664 
00665         if (!policy || !rule) {
00666                 ERR(policy, "%s", strerror(EINVAL));
00667                 errno = EINVAL;
00668                 return NULL;
00669         }
00670 
00671         /* rule type */
00672         if (qpol_terule_get_rule_type(policy->p, rule, &rule_type)) {
00673                 error = errno;
00674                 errno = error;
00675                 return NULL;
00676         }
00677         if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
00678                 ERR(policy, "%s", "Invalid type rule type");
00679                 errno = EINVAL;
00680                 return NULL;
00681         }
00682         if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00683                 ERR(policy, "%s", "Type rule has multiple rule types?");
00684                 errno = EINVAL;
00685                 return NULL;
00686         }
00687         if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00688                 error = error;
00689                 ERR(policy, "%s", strerror(error));
00690                 goto err;
00691         }
00692 
00693         /* source type */
00694         if (qpol_terule_get_source_type(policy->p, rule, &type)) {
00695                 error = errno;
00696                 goto err;
00697         }
00698         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00699                 error = errno;
00700                 goto err;
00701         }
00702         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00703                 error = error;
00704                 ERR(policy, "%s", strerror(error));
00705                 goto err;
00706         }
00707 
00708         /* target type */
00709         if (qpol_terule_get_target_type(policy->p, rule, &type)) {
00710                 error = errno;
00711                 goto err;
00712         }
00713         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00714                 error = errno;
00715                 goto err;
00716         }
00717         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " : ")) {
00718                 error = error;
00719                 ERR(policy, "%s", strerror(error));
00720                 goto err;
00721         }
00722 
00723         /* object class */
00724         if (qpol_terule_get_object_class(policy->p, rule, &obj_class)) {
00725                 error = errno;
00726                 goto err;
00727         }
00728         if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
00729                 error = errno;
00730                 goto err;
00731         }
00732         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00733                 error = error;
00734                 ERR(policy, "%s", strerror(error));
00735                 goto err;
00736         }
00737 
00738         /* default type */
00739         if (qpol_terule_get_default_type(policy->p, rule, &type)) {
00740                 error = errno;
00741                 goto err;
00742         }
00743         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00744                 error = errno;
00745                 goto err;
00746         }
00747         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, ";")) {
00748                 error = error;
00749                 ERR(policy, "%s", strerror(error));
00750                 goto err;
00751         }
00752 
00753         return tmp;
00754 
00755       err:
00756         free(tmp);
00757         errno = error;
00758         return NULL;
00759 }

char* apol_syn_terule_render const apol_policy_t policy,
const qpol_syn_terule_t rule
 

Render a syntactic terule 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 761 of file terule-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_TYPE_CHANGE, QPOL_RULE_TYPE_TRANS, qpol_syn_terule_get_class_iter(), qpol_syn_terule_get_default_type(), qpol_syn_terule_get_rule_type(), qpol_syn_terule_get_source_type_set(), qpol_syn_terule_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 print_syn_te_results().

00762 {
00763         char *tmp = NULL;
00764         const char *tmp_name = NULL;
00765         const char *rule_type_str;
00766         int error = 0;
00767         uint32_t rule_type = 0, star = 0, comp = 0;
00768         const qpol_type_t *type = NULL;
00769         const qpol_class_t *obj_class = NULL;
00770         qpol_iterator_t *iter = NULL, *iter2 = NULL;
00771         size_t tmp_sz = 0, iter_sz = 0, iter2_sz = 0;
00772         const qpol_type_set_t *set = NULL;
00773 
00774         if (!policy || !rule) {
00775                 ERR(policy, "%s", strerror(EINVAL));
00776                 errno = EINVAL;
00777                 return NULL;
00778         }
00779 
00780         /* rule type */
00781         if (qpol_syn_terule_get_rule_type(policy->p, rule, &rule_type)) {
00782                 error = errno;
00783                 return NULL;
00784         }
00785         if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
00786                 ERR(policy, "%s", "Invalid te rule type");
00787                 errno = EINVAL;
00788                 return NULL;
00789         }
00790         if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00791                 ERR(policy, "%s", "Te rule has multiple rule types?");
00792                 errno = EINVAL;
00793                 return NULL;
00794         }
00795         if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00796                 error = error;
00797                 ERR(policy, "%s", strerror(error));
00798                 goto err;
00799         }
00800 
00801         /* source type set */
00802         if (qpol_syn_terule_get_source_type_set(policy->p, rule, &set)) {
00803                 error = errno;
00804                 goto err;
00805         }
00806         if (qpol_type_set_get_is_star(policy->p, set, &star)) {
00807                 error = errno;
00808                 goto err;
00809         }
00810         if (star) {
00811                 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
00812                         error = error;
00813                         ERR(policy, "%s", strerror(error));
00814                         goto err;
00815                 }
00816         } else {
00817                 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
00818                         error = errno;
00819                         goto err;
00820                 }
00821                 if (comp) {
00822                         if (apol_str_append(&tmp, &tmp_sz, "~")) {
00823                                 error = error;
00824                                 ERR(policy, "%s", strerror(error));
00825                                 goto err;
00826                         }
00827                 }
00828                 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
00829                         error = errno;
00830                         goto err;
00831                 }
00832                 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
00833                         error = errno;
00834                         goto err;
00835                 }
00836                 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
00837                         error = errno;
00838                         ERR(policy, "%s", strerror(error));
00839                         goto err;
00840                 }
00841                 if (iter_sz + iter2_sz > 1) {
00842                         if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00843                                 error = error;
00844                                 ERR(policy, "%s", strerror(error));
00845                                 goto err;
00846                         }
00847                 }
00848                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00849                         if (qpol_iterator_get_item(iter, (void **)&type)) {
00850                                 error = errno;
00851                                 ERR(policy, "%s", strerror(error));
00852                                 goto err;
00853                         }
00854                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00855                                 error = errno;
00856                                 goto err;
00857                         }
00858                         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00859                                 error = error;
00860                                 ERR(policy, "%s", strerror(error));
00861                                 goto err;
00862                         }
00863                 }
00864                 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
00865                         if (qpol_iterator_get_item(iter2, (void **)&type)) {
00866                                 error = errno;
00867                                 ERR(policy, "%s", strerror(error));
00868                                 goto err;
00869                         }
00870                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00871                                 error = errno;
00872                                 goto err;
00873                         }
00874                         if (apol_str_append(&tmp, &tmp_sz, "-") ||
00875                             apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00876                                 error = error;
00877                                 ERR(policy, "%s", strerror(error));
00878                                 goto err;
00879                         }
00880                 }
00881                 qpol_iterator_destroy(&iter);
00882                 qpol_iterator_destroy(&iter2);
00883                 if (iter_sz + iter2_sz > 1) {
00884                         if (apol_str_append(&tmp, &tmp_sz, "} ")) {
00885                                 error = error;
00886                                 ERR(policy, "%s", strerror(error));
00887                                 goto err;
00888                         }
00889                 }
00890         }
00891 
00892         /* target type set */
00893         if (qpol_syn_terule_get_target_type_set(policy->p, rule, &set)) {
00894                 error = errno;
00895                 goto err;
00896         }
00897         if (qpol_type_set_get_is_star(policy->p, set, &star)) {
00898                 error = errno;
00899                 goto err;
00900         }
00901         if (star) {
00902                 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
00903                         error = error;
00904                         ERR(policy, "%s", strerror(error));
00905                         goto err;
00906                 }
00907         } else {
00908                 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
00909                         error = errno;
00910                         goto err;
00911                 }
00912                 if (comp) {
00913                         if (apol_str_append(&tmp, &tmp_sz, "~")) {
00914                                 error = error;
00915                                 ERR(policy, "%s", strerror(error));
00916                                 goto err;
00917                         }
00918                 }
00919                 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
00920                         error = errno;
00921                         goto err;
00922                 }
00923                 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
00924                         error = errno;
00925                         goto err;
00926                 }
00927                 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
00928                         error = errno;
00929                         ERR(policy, "%s", strerror(error));
00930                         goto err;
00931                 }
00932                 if (iter_sz + iter2_sz > 1) {
00933                         if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00934                                 error = error;
00935                                 ERR(policy, "%s", strerror(error));
00936                                 goto err;
00937                         }
00938                 }
00939                 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00940                         if (qpol_iterator_get_item(iter, (void **)&type)) {
00941                                 error = errno;
00942                                 ERR(policy, "%s", strerror(error));
00943                                 goto err;
00944                         }
00945                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00946                                 error = errno;
00947                                 goto err;
00948                         }
00949                         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00950                                 error = error;
00951                                 ERR(policy, "%s", strerror(error));
00952                                 goto err;
00953                         }
00954                 }
00955                 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
00956                         if (qpol_iterator_get_item(iter2, (void **)&type)) {
00957                                 error = errno;
00958                                 ERR(policy, "%s", strerror(error));
00959                                 goto err;
00960                         }
00961                         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00962                                 error = errno;
00963                                 goto err;
00964                         }
00965                         if (apol_str_append(&tmp, &tmp_sz, "-") ||
00966                             apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00967                                 error = error;
00968                                 ERR(policy, "%s", strerror(error));
00969                                 goto err;
00970                         }
00971                 }
00972                 qpol_iterator_destroy(&iter);
00973                 qpol_iterator_destroy(&iter2);
00974                 if (iter_sz + iter2_sz > 1) {
00975                         if (apol_str_append(&tmp, &tmp_sz, "} ")) {
00976                                 error = error;
00977                                 ERR(policy, "%s", strerror(error));
00978                                 goto err;
00979                         }
00980                 }
00981         }
00982 
00983         if (apol_str_append(&tmp, &tmp_sz, ": ")) {
00984                 error = error;
00985                 ERR(policy, "%s", strerror(error));
00986                 goto err;
00987         }
00988 
00989         /* object classes */
00990         if (qpol_syn_terule_get_class_iter(policy->p, rule, &iter)) {
00991                 error = errno;
00992                 goto err;
00993         }
00994         if (qpol_iterator_get_size(iter, &iter_sz)) {
00995                 error = errno;
00996                 ERR(policy, "%s", strerror(error));
00997                 goto err;
00998         }
00999         if (iter_sz > 1) {
01000                 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
01001                         error = errno;
01002                         ERR(policy, "%s", strerror(error));
01003                         goto err;
01004                 }
01005         }
01006         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
01007                 if (qpol_iterator_get_item(iter, (void **)&obj_class)) {
01008                         error = errno;
01009                         ERR(policy, "%s", strerror(error));
01010                         goto err;
01011                 }
01012                 if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
01013                         error = errno;
01014                         goto err;
01015                 }
01016                 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01017                         error = errno;
01018                         ERR(policy, "%s", strerror(error));
01019                         goto err;
01020                 }
01021         }
01022         qpol_iterator_destroy(&iter);
01023         if (iter_sz > 1) {
01024                 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01025                         error = errno;
01026                         ERR(policy, "%s", strerror(error));
01027                         goto err;
01028                 }
01029         }
01030 
01031         /* default type */
01032         if (qpol_syn_terule_get_default_type(policy->p, rule, &type)) {
01033                 error = errno;
01034                 goto err;
01035         }
01036         if (qpol_type_get_name(policy->p, type, &tmp_name)) {
01037                 error = errno;
01038                 goto err;
01039         }
01040         if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, ";")) {
01041                 error = errno;
01042                 ERR(policy, "%s", strerror(error));
01043                 goto err;
01044         }
01045 
01046         return tmp;
01047 
01048       err:
01049         free(tmp);
01050         qpol_iterator_destroy(&iter);
01051         qpol_iterator_destroy(&iter2);
01052         errno = error;
01053         return NULL;
01054 }