poldiff.c File Reference


Detailed Description

Implementation for computing a semantic policy difference.

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

#include <config.h>
#include "poldiff_internal.h"
#include <poldiff/component_record.h>
#include <apol/util.h>
#include <qpol/policy_extend.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

Go to the source code of this file.


Classes

struct  poldiff_component_record
 All policy items (object classes, types, rules, etc.) must implement at least these functions. More...

Functions

const poldiff_component_record_tpoldiff_get_component_record (uint32_t which)
 Get the poldiff_component_record_t for a particular policy component.
poldiff_tpoldiff_create (apol_policy_t *orig_policy, apol_policy_t *mod_policy, poldiff_handle_fn_t fn, void *callback_arg)
 Allocate and initialize a new policy difference structure.
void poldiff_destroy (poldiff_t **diff)
 Free all memory used by a policy difference structure and set it to NULL.
int poldiff_do_item_diff (poldiff_t *diff, const poldiff_component_record_t *component_record)
 Given a particular policy item record (e.g., one for object classes), (re-)perform a diff of them between the two policies listed in the poldiff_t structure.
int poldiff_run (poldiff_t *diff, uint32_t flags)
 Run the difference algorithm for the selected policy components/rules.
int poldiff_is_run (const poldiff_t *diff, uint32_t flags)
 Determine if a particular policy component/rule diff was actually run yet or not.
int poldiff_get_stats (const poldiff_t *diff, uint32_t flags, size_t stats[5])
 Get a total of the differences of each form for a given item (or set of items).
int poldiff_enable_line_numbers (poldiff_t *diff)
 Enable line numbers for all rule differences.
int poldiff_build_bsts (poldiff_t *diff)
 Build the BST for classes, permissions, and booleans if the policies have changed.
void poldiff_handle_default_callback (void *arg __attribute__((unused)), poldiff_t *p __attribute__((unused)), int level, const char *fmt, va_list va_args)
void poldiff_handle_msg (const poldiff_t *p, int level, const char *fmt,...)
poldiff_item_get_form_fn_t poldiff_component_record_get_form_fn (const poldiff_component_record_t *diff)
 Get the function that will return the form from a poldiff_component_record_t.
poldiff_item_to_string_fn_t poldiff_component_record_get_to_string_fn (const poldiff_component_record_t *diff)
 Get the function that will return the to_string from a poldiff_component_record_t.
poldiff_get_item_stats_fn_t poldiff_component_record_get_stats_fn (const poldiff_component_record_t *diff)
 Get the function that will return the item_stats from a poldiff_component_record_t.
poldiff_get_result_items_fn_t poldiff_component_record_get_results_fn (const poldiff_component_record_t *diff)
 Get the function that will return the results from a poldiff_component_record_t.
const char * poldiff_component_record_get_label (const poldiff_component_record_t *diff)
 Get the function that will return the label from a poldiff_component_record_t.

Variables

const poldiff_component_record_t component_records []

Function Documentation

const poldiff_component_record_t* poldiff_get_component_record uint32_t  which  ) 
 

Get the poldiff_component_record_t for a particular policy component.

Consult this record for function pointers, so as to achieve a limited form of polymorphism.

Parameters:
which Flag (as defined in <poldiff/poldiff.h>) indicating which component to look up.
Returns:
A poldiff_component_record_t associated with the component or NULL if not found.

Definition at line 306 of file poldiff.c.

References component_records, poldiff_component_record::flag_bit, and poldiff_component_record_t.

Referenced by print_attrib_diffs(), print_avallow_diffs(), print_avauditallow_diffs(), print_avdontaudit_diffs(), print_avneverallow_diffs(), print_bool_diffs(), print_cat_diffs(), print_class_diffs(), print_common_diffs(), print_diff(), print_level_diffs(), print_range_trans_diffs(), print_role_allow_diffs(), print_role_diffs(), print_role_trans_diffs(), print_type_diffs(), print_user_diffs(), result_item_create_from_flag(), and result_item_create_terules_from_flag().

00307 {
00308         size_t i = 0;
00309         size_t num_items;
00310 
00311         num_items = sizeof(component_records) / sizeof(poldiff_component_record_t);
00312         for (i = 0; i < num_items; i++) {
00313                 if (component_records[i].flag_bit == which)
00314                         return &component_records[i];
00315         }
00316         return NULL;
00317 }

poldiff_t* poldiff_create apol_policy_t orig_policy,
apol_policy_t mod_policy,
poldiff_handle_fn_t  fn,
void *  callback_arg
 

Allocate and initialize a new policy difference structure.

This function takes ownership of the supplied policies and will handle their destruction upon poldiff_destroy(). The poldiff object will be responsible for rebuilding the policy (such as if neverallows are requested). It is still safe to access elements within the policies, but avoid making changes to the policy while the poldiff object still exists.

Parameters:
orig_policy The original policy.
mod_policy The new (modified) policy.
fn Function to be called by the error handler. If NULL then write messages to standard error.
callback_arg Argument for the callback.
Returns:
a newly allocated and initialized difference structure or NULL on error; if the call fails, errno will be set. The caller is responsible for calling poldiff_destroy() to free memory used by this structure.

Definition at line 319 of file poldiff.c.

References apol_policy_get_qpol(), apol_policy_t, poldiff::attrib_diffs, attrib_summary_create(), avrule_create(), poldiff::avrule_diffs, bool_create(), poldiff::bool_diffs, cat_create(), poldiff::cat_diffs, class_create(), poldiff::class_diffs, common_create(), poldiff::common_diffs, diff, ERR, poldiff::fn, poldiff::handle_arg, level_create(), poldiff::level_diffs, poldiff::mod_pol, poldiff::mod_qpol, poldiff::orig_pol, orig_policy, poldiff::orig_qpol, poldiff_destroy(), poldiff_t, poldiff::policy_opts, QPOL_POLICY_OPTION_NO_RULES, range_trans_create(), poldiff::range_trans_diffs, role_allow_create(), poldiff::role_allow_diffs, role_create(), poldiff::role_diffs, role_trans_create(), poldiff::role_trans_diffs, terule_create(), poldiff::terule_diffs, poldiff::type_diffs, poldiff::type_map, type_map_create(), type_map_infer(), type_summary_create(), user_create(), and poldiff::user_diffs.

Referenced by init_poldiff(), main(), and sediffx_get_poldiff().

00320 {
00321         poldiff_t *diff = NULL;
00322         int error;
00323 
00324         if (!orig_policy || !mod_policy) {
00325                 ERR(NULL, "%s", strerror(EINVAL));
00326                 errno = EINVAL;
00327                 return NULL;
00328         }
00329 
00330         if (!(diff = calloc(1, sizeof(poldiff_t)))) {
00331                 ERR(NULL, "%s", strerror(ENOMEM));
00332                 errno = ENOMEM;
00333                 return NULL;
00334         }
00335         diff->orig_pol = orig_policy;
00336         diff->mod_pol = mod_policy;
00337         diff->orig_qpol = apol_policy_get_qpol(diff->orig_pol);
00338         diff->mod_qpol = apol_policy_get_qpol(diff->mod_pol);
00339         diff->fn = fn;
00340         diff->handle_arg = callback_arg;
00341         if ((diff->type_map = type_map_create()) == NULL) {
00342                 ERR(diff, "%s", strerror(ENOMEM));
00343                 poldiff_destroy(&diff);
00344                 errno = ENOMEM;
00345                 return NULL;
00346         }
00347         if (type_map_infer(diff) < 0) {
00348                 error = errno;
00349                 poldiff_destroy(&diff);
00350                 errno = error;
00351                 return NULL;
00352         }
00353 
00354         if ((diff->attrib_diffs = attrib_summary_create()) == NULL ||
00355             (diff->avrule_diffs[AVRULE_OFFSET_ALLOW] = avrule_create()) == NULL ||
00356             (diff->avrule_diffs[AVRULE_OFFSET_AUDITALLOW] = avrule_create()) == NULL ||
00357             (diff->avrule_diffs[AVRULE_OFFSET_DONTAUDIT] = avrule_create()) == NULL ||
00358             (diff->avrule_diffs[AVRULE_OFFSET_NEVERALLOW] = avrule_create()) == NULL ||
00359             (diff->bool_diffs = bool_create()) == NULL ||
00360             (diff->cat_diffs = cat_create()) == NULL ||
00361             (diff->class_diffs = class_create()) == NULL ||
00362             (diff->common_diffs = common_create()) == NULL ||
00363             (diff->level_diffs = level_create()) == NULL ||
00364             (diff->range_trans_diffs = range_trans_create()) == NULL ||
00365             (diff->role_diffs = role_create()) == NULL ||
00366             (diff->role_allow_diffs = role_allow_create()) == NULL ||
00367             (diff->role_trans_diffs = role_trans_create()) == NULL ||
00368             (diff->terule_diffs[TERULE_OFFSET_CHANGE] = terule_create()) == NULL ||
00369             (diff->terule_diffs[TERULE_OFFSET_MEMBER] = terule_create()) == NULL ||
00370             (diff->terule_diffs[TERULE_OFFSET_TRANS] = terule_create()) == NULL ||
00371             (diff->type_diffs = type_summary_create()) == NULL || (diff->user_diffs = user_create()) == NULL) {
00372                 ERR(diff, "%s", strerror(ENOMEM));
00373                 poldiff_destroy(&diff);
00374                 errno = ENOMEM;
00375                 return NULL;
00376         }
00377 
00378         diff->policy_opts = QPOL_POLICY_OPTION_NO_RULES | QPOL_POLICY_OPTION_NO_NEVERALLOWS;
00379         return diff;
00380 }

void poldiff_destroy poldiff_t **  diff  ) 
 

Free all memory used by a policy difference structure and set it to NULL.

Parameters:
diff Reference pointer to the difference structure to destroy. This pointer will be set to NULL. (If already NULL, function is a no-op.)

Definition at line 382 of file poldiff.c.

References apol_bst_destroy(), apol_policy_destroy(), attrib_summary_destroy(), avrule_destroy(), AVRULE_OFFSET_ALLOW, AVRULE_OFFSET_AUDITALLOW, AVRULE_OFFSET_DONTAUDIT, AVRULE_OFFSET_NEVERALLOW, bool_destroy(), cat_destroy(), class_destroy(), common_destroy(), diff, level_destroy(), poldiff_t, range_trans_destroy(), role_allow_destroy(), role_destroy(), role_trans_destroy(), terule_destroy(), TERULE_OFFSET_CHANGE, TERULE_OFFSET_MEMBER, TERULE_OFFSET_TRANS, type_map_destroy(), type_summary_destroy(), and user_destroy().

Referenced by init_poldiff(), main(), poldiff_cleanup(), poldiff_create(), sediffx_destroy(), and sediffx_set_policy().

00383 {
00384         if (!diff || !(*diff))
00385                 return;
00386         apol_policy_destroy(&(*diff)->orig_pol);
00387         apol_policy_destroy(&(*diff)->mod_pol);
00388         apol_bst_destroy(&(*diff)->class_bst);
00389         apol_bst_destroy(&(*diff)->perm_bst);
00390         apol_bst_destroy(&(*diff)->bool_bst);
00391 
00392         type_map_destroy(&(*diff)->type_map);
00393         attrib_summary_destroy(&(*diff)->attrib_diffs);
00394         avrule_destroy(&(*diff)->avrule_diffs[AVRULE_OFFSET_ALLOW]);
00395         avrule_destroy(&(*diff)->avrule_diffs[AVRULE_OFFSET_AUDITALLOW]);
00396         avrule_destroy(&(*diff)->avrule_diffs[AVRULE_OFFSET_DONTAUDIT]);
00397         avrule_destroy(&(*diff)->avrule_diffs[AVRULE_OFFSET_NEVERALLOW]);
00398         bool_destroy(&(*diff)->bool_diffs);
00399         cat_destroy(&(*diff)->cat_diffs);
00400         class_destroy(&(*diff)->class_diffs);
00401         common_destroy(&(*diff)->common_diffs);
00402         level_destroy(&(*diff)->level_diffs);
00403         range_trans_destroy(&(*diff)->range_trans_diffs);
00404         role_destroy(&(*diff)->role_diffs);
00405         role_allow_destroy(&(*diff)->role_allow_diffs);
00406         role_trans_destroy(&(*diff)->role_trans_diffs);
00407         user_destroy(&(*diff)->user_diffs);
00408         terule_destroy(&(*diff)->terule_diffs[TERULE_OFFSET_CHANGE]);
00409         terule_destroy(&(*diff)->terule_diffs[TERULE_OFFSET_MEMBER]);
00410         terule_destroy(&(*diff)->terule_diffs[TERULE_OFFSET_TRANS]);
00411         type_summary_destroy(&(*diff)->type_diffs);
00412         free(*diff);
00413         *diff = NULL;
00414 }

int poldiff_do_item_diff poldiff_t diff,
const poldiff_component_record_t component_record
[static]
 

Given a particular policy item record (e.g., one for object classes), (re-)perform a diff of them between the two policies listed in the poldiff_t structure.

Upon success, set the status flag within 'diff' to indicate that this diff is done.

Parameters:
diff The policy difference structure containing the policies to compare and to populate with the item differences.
component_record Item record containg callbacks to perform each step of the computation for a particular kind of item.
Returns:
0 on success and < 0 on error; if the call fails; errno will be set and the only defined operation on the policy difference structure will be poldiff_destroy().

Definition at line 431 of file poldiff.c.

References apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, poldiff_component_record::comp, poldiff_component_record::deep_diff, diff, poldiff::diff_status, ERR, poldiff_component_record::flag_bit, poldiff_component_record::get_items, INFO, poldiff_component_record::item_name, poldiff::mod_pol, poldiff_component_record::new_diff, poldiff::orig_pol, poldiff_component_record_t, POLDIFF_FORM_ADDED, POLDIFF_FORM_REMOVED, and poldiff_t.

Referenced by poldiff_run().

00432 {
00433         apol_vector_t *p1_v = NULL, *p2_v = NULL;
00434         int error = 0, retv;
00435         size_t x = 0, y = 0;
00436         void *item_x = NULL, *item_y = NULL;
00437 
00438         if (!diff || !component_record) {
00439                 ERR(diff, "%s", strerror(EINVAL));
00440                 errno = EINVAL;
00441                 return -1;
00442         }
00443         diff->diff_status &= (~component_record->flag_bit);
00444 
00445         INFO(diff, "Getting %s items from original policy.", component_record->item_name);
00446         p1_v = component_record->get_items(diff, diff->orig_pol);
00447         if (!p1_v) {
00448                 error = errno;
00449                 goto err;
00450         }
00451 
00452         INFO(diff, "Getting %s items from modified policy.", component_record->item_name);
00453         p2_v = component_record->get_items(diff, diff->mod_pol);
00454         if (!p2_v) {
00455                 error = errno;
00456                 goto err;
00457         }
00458 
00459         INFO(diff, "Finding differences in %s.", component_record->item_name);
00460         for (x = 0, y = 0; x < apol_vector_get_size(p1_v);) {
00461                 if (y >= apol_vector_get_size(p2_v))
00462                         break;
00463                 item_x = apol_vector_get_element(p1_v, x);
00464                 item_y = apol_vector_get_element(p2_v, y);
00465                 retv = component_record->comp(item_x, item_y, diff);
00466                 if (retv < 0) {
00467                         if (component_record->new_diff(diff, POLDIFF_FORM_REMOVED, item_x)) {
00468                                 error = errno;
00469                                 goto err;
00470                         }
00471                         x++;
00472                 } else if (retv > 0) {
00473                         if (component_record->new_diff(diff, POLDIFF_FORM_ADDED, item_y)) {
00474                                 error = errno;
00475                                 goto err;
00476                         }
00477                         y++;
00478                 } else {
00479                         if (component_record->deep_diff(diff, item_x, item_y)) {
00480                                 error = errno;
00481                                 goto err;
00482                         }
00483                         x++;
00484                         y++;
00485                 }
00486         }
00487         for (; x < apol_vector_get_size(p1_v); x++) {
00488                 item_x = apol_vector_get_element(p1_v, x);
00489                 if (component_record->new_diff(diff, POLDIFF_FORM_REMOVED, item_x)) {
00490                         error = errno;
00491                         goto err;
00492                 }
00493         }
00494         for (; y < apol_vector_get_size(p2_v); y++) {
00495                 item_y = apol_vector_get_element(p2_v, y);
00496                 if (component_record->new_diff(diff, POLDIFF_FORM_ADDED, item_y)) {
00497                         error = errno;
00498                         goto err;
00499                 }
00500         }
00501 
00502         apol_vector_destroy(&p1_v);
00503         apol_vector_destroy(&p2_v);
00504         diff->diff_status |= component_record->flag_bit;
00505         return 0;
00506       err:
00507         apol_vector_destroy(&p1_v);
00508         apol_vector_destroy(&p2_v);
00509         errno = error;
00510         return -1;
00511 }

int poldiff_run poldiff_t diff,
uint32_t  flags
 

Run the difference algorithm for the selected policy components/rules.

Parameters:
diff The policy difference structure for which to compute the differences.
flags Bit-wise or'd set of POLDIFF_DIFF_* from above indicating the components and rules for which to compute the difference. If an item has already been computed the flag for that item is ignored.
Returns:
0 on success or < 0 on error; if the call fails, errno will be set and the only defined operation on the difference structure is poldiff_destroy().

Definition at line 513 of file poldiff.c.

References component_records, diff, poldiff::diff_status, ERR, poldiff_component_record::flag_bit, INFO, poldiff::line_numbers_enabled, poldiff::mod_qpol, poldiff::orig_qpol, poldiff_component_record_t, POLDIFF_DIFF_AVRULES, poldiff_do_item_diff(), poldiff_t, poldiff::policy_opts, qpol_policy_rebuild(), poldiff::remapped, poldiff_component_record::reset, and type_map_build().

Referenced by init_poldiff(), main(), and toplevel_run_diff_runner().

00514 {
00515         size_t i, num_items;
00516 
00517         if (!flags)
00518                 return 0;              /* nothing to do */
00519 
00520         if (!diff) {
00521                 ERR(diff, "%s", strerror(EINVAL));
00522                 errno = EINVAL;
00523                 return -1;
00524         }
00525 
00526         int policy_opts = diff->policy_opts;
00527         if (flags & (POLDIFF_DIFF_AVRULES | POLDIFF_DIFF_TERULES)) {
00528                 policy_opts &= ~(QPOL_POLICY_OPTION_NO_RULES);
00529         }
00530         if (flags & POLDIFF_DIFF_AVNEVERALLOW) {
00531                 policy_opts &= ~(QPOL_POLICY_OPTION_NO_NEVERALLOWS);
00532         }
00533         if (policy_opts != diff->policy_opts) {
00534                 INFO(diff, "%s", "Loading rules from original policy.");
00535                 if (qpol_policy_rebuild(diff->orig_qpol, policy_opts)) {
00536                         return -1;
00537                 }
00538                 INFO(diff, "%s", "Loading rules from modified policy.");
00539                 if (qpol_policy_rebuild(diff->mod_qpol, policy_opts)) {
00540                         return -1;
00541                 }
00542                 // force flushing of existing pointers into policies
00543                 diff->remapped = 1;
00544                 diff->policy_opts = policy_opts;
00545         }
00546 
00547         num_items = sizeof(component_records) / sizeof(poldiff_component_record_t);
00548         if (diff->remapped) {
00549                 for (i = 0; i < num_items; i++) {
00550                         if (component_records[i].flag_bit & POLDIFF_DIFF_REMAPPED) {
00551                                 INFO(diff, "Resetting %s diff.", component_records[i].item_name);
00552                                 if (component_records[i].reset(diff))
00553                                         return -1;
00554                         }
00555                 }
00556                 diff->diff_status &= ~(POLDIFF_DIFF_REMAPPED);
00557                 diff->remapped = 0;
00558         }
00559 
00560         INFO(diff, "%s", "Building type map.");
00561         if (type_map_build(diff)) {
00562                 return -1;
00563         }
00564 
00565         diff->line_numbers_enabled = 0;
00566         for (i = 0; i < num_items; i++) {
00567                 /* item requested but not yet run */
00568                 if ((flags & component_records[i].flag_bit) && !(component_records[i].flag_bit & diff->diff_status)) {
00569                         INFO(diff, "Running %s diff.", component_records[i].item_name);
00570                         if (poldiff_do_item_diff(diff, &(component_records[i]))) {
00571                                 return -1;
00572                         }
00573                 }
00574         }
00575 
00576         return 0;
00577 }

int poldiff_is_run const poldiff_t diff,
uint32_t  flags
 

Determine if a particular policy component/rule diff was actually run yet or not.

Parameters:
diff The policy difference structure for which to compute the differences.
flags Bit-wise or'd set of POLDIFF_DIFF_* from above indicating which components/rules diffs were run.
Returns:
1 if all indicated diffs were run, 0 if any were not, < 0 on error.

Definition at line 579 of file poldiff.c.

References diff, poldiff::diff_status, ERR, and poldiff_t.

Referenced by result_item_role_trans_get_forms(), and result_item_single_get_forms().

00580 {
00581         if (!flags)
00582                 return 1;              /* nothing to do */
00583 
00584         if (!diff) {
00585                 ERR(diff, "%s", strerror(EINVAL));
00586                 errno = EINVAL;
00587                 return -1;
00588         }
00589         if ((diff->diff_status & flags) == flags) {
00590                 return 1;
00591         }
00592         return 0;
00593 }

int poldiff_get_stats const poldiff_t diff,
uint32_t  flags,
size_t  stats[5]
 

Get a total of the differences of each form for a given item (or set of items).

Parameters:
diff The policy difference structure from which to get the stats.
flags Bit-wise or'd set of POLDIFF_DIFF_* from above indicating the items for which to get the total differences. If more that one bit is set differences of the same form are totaled for all specified items.
stats Array into which to write the numbers (array must be pre-allocated). The order of the values written to the array is as follows: number of items of form POLDIFF_FORM_ADDED, number of POLDIFF_FORM_REMOVED, number of POLDIFF_FORM_MODIFIED, number of form POLDIFF_FORM_ADD_TYPE, and number of POLDIFF_FORM_REMOVE_TYPE.
Returns:
0 on success and < 0 on error; if the call fails, errno will be set.

Definition at line 595 of file poldiff.c.

References component_records, diff, ERR, poldiff_component_record::flag_bit, poldiff_component_record::get_stats, poldiff_component_record_t, and poldiff_t.

Referenced by get_diff_total(), result_item_role_trans_get_forms(), and result_item_single_get_forms().

00596 {
00597         size_t i, j, num_items, tmp_stats[5] = { 0, 0, 0, 0, 0 };
00598 
00599         if (!diff || !flags) {
00600                 ERR(diff, "%s", strerror(EINVAL));
00601                 errno = EINVAL;
00602                 return -1;
00603         }
00604 
00605         stats[0] = stats[1] = stats[2] = stats[3] = stats[4] = 0;
00606 
00607         num_items = sizeof(component_records) / sizeof(poldiff_component_record_t);
00608         for (i = 0; i < num_items; i++) {
00609                 if (flags & component_records[i].flag_bit) {
00610                         component_records[i].get_stats(diff, tmp_stats);
00611                         for (j = 0; j < 5; j++)
00612                                 stats[j] += tmp_stats[j];
00613                 }
00614         }
00615 
00616         return 0;
00617 }

int poldiff_enable_line_numbers poldiff_t diff  ) 
 

Enable line numbers for all rule differences.

If not called, line numbers will not be available when displaying differences. This function is safe to call multiple times and will have no effect after the first time. It also has no effect if one policy (or both of them) does not support line numbers. Be aware that line numbers will need to be re-enabled each time poldiff_run() is called.

Parameters:
diff The policy difference structure.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and the difference structure should be destroyed.

Definition at line 619 of file poldiff.c.

References avrule_enable_line_numbers(), AVRULE_OFFSET_ALLOW, AVRULE_OFFSET_AUDITALLOW, AVRULE_OFFSET_DONTAUDIT, AVRULE_OFFSET_NEVERALLOW, diff, poldiff::line_numbers_enabled, poldiff::mod_qpol, poldiff::orig_qpol, poldiff_t, qpol_policy_build_syn_rule_table(), terule_enable_line_numbers(), TERULE_OFFSET_CHANGE, TERULE_OFFSET_MEMBER, and TERULE_OFFSET_TRANS.

Referenced by toplevel_run_diff_runner().

00620 {
00621         int retval;
00622         if (diff == NULL) {
00623                 errno = EINVAL;
00624                 return -1;
00625         }
00626         if (!diff->line_numbers_enabled) {
00627                 if (qpol_policy_build_syn_rule_table(diff->orig_qpol))
00628                         return -1;
00629                 if (qpol_policy_build_syn_rule_table(diff->mod_qpol))
00630                         return -1;
00631                 if ((retval = avrule_enable_line_numbers(diff, AVRULE_OFFSET_ALLOW)) < 0) {
00632                         return retval;
00633                 }
00634                 if ((retval = avrule_enable_line_numbers(diff, AVRULE_OFFSET_AUDITALLOW)) < 0) {
00635                         return retval;
00636                 }
00637                 if ((retval = avrule_enable_line_numbers(diff, AVRULE_OFFSET_DONTAUDIT)) < 0) {
00638                         return retval;
00639                 }
00640                 if ((retval = avrule_enable_line_numbers(diff, AVRULE_OFFSET_NEVERALLOW)) < 0) {
00641                         return retval;
00642                 }
00643                 if ((retval = terule_enable_line_numbers(diff, TERULE_OFFSET_CHANGE)) < 0) {
00644                         return retval;
00645                 }
00646                 if ((retval = terule_enable_line_numbers(diff, TERULE_OFFSET_MEMBER)) < 0) {
00647                         return retval;
00648                 }
00649                 if ((retval = terule_enable_line_numbers(diff, TERULE_OFFSET_TRANS)) < 0) {
00650                         return retval;
00651                 }
00652                 diff->line_numbers_enabled = 1;
00653         }
00654         return 0;
00655 }

int poldiff_build_bsts poldiff_t diff  ) 
 

Build the BST for classes, permissions, and booleans if the policies have changed.

This effectively provides a partial mapping of rules from one policy to the other.

Parameters:
diff Policy difference structure containing policies to diff.
Returns:
0 on success, < 0 on error.

Definition at line 657 of file poldiff.c.

References apol_bool_get_by_query(), apol_bst_create(), apol_bst_insert_and_get(), apol_class_get_by_query(), apol_perm_get_by_query(), apol_policy_get_qpol(), apol_policy_t, apol_str_strcmp(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, poldiff::bool_bst, poldiff::class_bst, diff, ERR, poldiff::mod_pol, poldiff::orig_pol, poldiff::perm_bst, poldiff_t, qpol_bool_get_name(), qpol_bool_t, qpol_class_get_name(), qpol_class_t, and qpol_policy_t.

Referenced by avrule_get_items(), and terule_get_items().

00658 {
00659         apol_vector_t *classes[2] = { NULL, NULL };
00660         apol_vector_t *perms[2] = { NULL, NULL };
00661         apol_vector_t *bools[2] = { NULL, NULL };
00662         size_t i, j;
00663         const qpol_class_t *cls;
00664         qpol_bool_t *qbool;
00665         const char *name;
00666         char *new_name;
00667         int retval = -1, error = 0;
00668         if (diff->class_bst != NULL) {
00669                 return 0;
00670         }
00671         if ((diff->class_bst = apol_bst_create(apol_str_strcmp, free)) == NULL ||
00672             (diff->perm_bst = apol_bst_create(apol_str_strcmp, free)) == NULL ||
00673             (diff->bool_bst = apol_bst_create(apol_str_strcmp, free)) == NULL) {
00674                 error = errno;
00675                 ERR(diff, "%s", strerror(error));
00676                 goto cleanup;
00677         }
00678         for (i = 0; i < 2; i++) {
00679                 apol_policy_t *p = (i == 0 ? diff->orig_pol : diff->mod_pol);
00680                 qpol_policy_t *q = apol_policy_get_qpol(p);
00681                 if (apol_class_get_by_query(p, NULL, &classes[i]) < 0 ||
00682                     apol_perm_get_by_query(p, NULL, &perms[i]) < 0 || apol_bool_get_by_query(p, NULL, &bools[i]) < 0) {
00683                         error = errno;
00684                         goto cleanup;
00685                 }
00686                 for (j = 0; j < apol_vector_get_size(classes[i]); j++) {
00687                         cls = apol_vector_get_element(classes[i], j);
00688                         if (qpol_class_get_name(q, cls, &name) < 0) {
00689                                 error = errno;
00690                                 goto cleanup;
00691                         }
00692                         if ((new_name = strdup(name)) == NULL ||
00693                             apol_bst_insert_and_get(diff->class_bst, (void **)&new_name, NULL) < 0) {
00694                                 error = errno;
00695                                 ERR(diff, "%s", strerror(error));
00696                                 goto cleanup;
00697                         }
00698                 }
00699                 for (j = 0; j < apol_vector_get_size(perms[i]); j++) {
00700                         name = (char *)apol_vector_get_element(perms[i], j);
00701                         if ((new_name = strdup(name)) == NULL ||
00702                             apol_bst_insert_and_get(diff->perm_bst, (void **)&new_name, NULL) < 0) {
00703                                 error = errno;
00704                                 ERR(diff, "%s", strerror(error));
00705                                 goto cleanup;
00706                         }
00707                 }
00708                 for (j = 0; j < apol_vector_get_size(bools[i]); j++) {
00709                         qbool = (qpol_bool_t *) apol_vector_get_element(bools[i], j);
00710                         if (qpol_bool_get_name(q, qbool, &name) < 0) {
00711                                 error = errno;
00712                                 goto cleanup;
00713                         }
00714                         if ((new_name = strdup(name)) == NULL ||
00715                             apol_bst_insert_and_get(diff->bool_bst, (void **)&new_name, NULL) < 0) {
00716                                 error = errno;
00717                                 ERR(diff, "%s", strerror(error));
00718                                 goto cleanup;
00719                         }
00720                 }
00721         }
00722         retval = 0;
00723       cleanup:
00724         apol_vector_destroy(&classes[0]);
00725         apol_vector_destroy(&classes[1]);
00726         apol_vector_destroy(&perms[0]);
00727         apol_vector_destroy(&perms[1]);
00728         apol_vector_destroy(&bools[0]);
00729         apol_vector_destroy(&bools[1]);
00730         errno = error;
00731         return retval;
00732 }

void poldiff_handle_default_callback void *arg   __attribute__((unused)),
poldiff_t *p   __attribute__((unused)),
int  level,
const char *  fmt,
va_list  va_args
[static]
 

Definition at line 734 of file poldiff.c.

References fmt, POLDIFF_MSG_ERR, POLDIFF_MSG_INFO, POLDIFF_MSG_WARN, and poldiff_t.

Referenced by poldiff_handle_msg().

00736 {
00737         switch (level) {
00738         case POLDIFF_MSG_INFO:
00739         {
00740                 /* by default do not display these messages */
00741                 return;
00742         }
00743         case POLDIFF_MSG_WARN:
00744         {
00745                 fprintf(stderr, "WARNING: ");
00746                 break;
00747         }
00748         case POLDIFF_MSG_ERR:
00749         default:
00750         {
00751                 fprintf(stderr, "ERROR: ");
00752                 break;
00753         }
00754         }
00755         vfprintf(stderr, fmt, va_args);
00756         fprintf(stderr, "\n");
00757 }

void poldiff_handle_msg const poldiff_t p,
int  level,
const char *  fmt,
  ...
 

Definition at line 759 of file poldiff.c.

References fmt, poldiff::fn, poldiff::handle_arg, level, poldiff_handle_default_callback(), and poldiff_t.

00760 {
00761         va_list ap;
00762         va_start(ap, fmt);
00763         if (p == NULL || p->fn == NULL) {
00764                 poldiff_handle_default_callback(NULL, NULL, level, fmt, ap);
00765         } else {
00766                 p->fn(p->handle_arg, p, level, fmt, ap);
00767         }
00768         va_end(ap);
00769 }

poldiff_item_get_form_fn_t poldiff_component_record_get_form_fn const poldiff_component_record_t comp  ) 
 

Get the function that will return the form from a poldiff_component_record_t.

Parameters:
comp Pointer to the component to extract the named virtual function.
Returns:
Function pointer relating to the passed in record key, or NULL upon error.

Definition at line 771 of file poldiff.c.

References diff, poldiff_component_record_t, and poldiff_item_get_form_fn_t.

Referenced by print_rule_section(), result_item_create_from_flag(), and result_item_create_terules_from_flag().

00772 {
00773         if (!diff) {
00774                 errno = EINVAL;
00775                 return NULL;
00776         }
00777         return diff->get_form;
00778 }

poldiff_item_to_string_fn_t poldiff_component_record_get_to_string_fn const poldiff_component_record_t diff  ) 
 

Get the function that will return the to_string from a poldiff_component_record_t.

Parameters:
diff Pointer to the component to extract the named virtual function.
Returns:
Function pointer relating to the passed in record key, or NULL upon error.

Definition at line 780 of file poldiff.c.

References diff, poldiff_component_record_t, and poldiff_item_to_string_fn_t.

Referenced by print_rule_section(), result_item_create_from_flag(), and result_item_create_terules_from_flag().

00781 {
00782         if (!diff) {
00783                 errno = EINVAL;
00784                 return NULL;
00785         }
00786         return diff->to_string;
00787 }

poldiff_get_item_stats_fn_t poldiff_component_record_get_stats_fn const poldiff_component_record_t diff  ) 
 

Get the function that will return the item_stats from a poldiff_component_record_t.

Parameters:
diff Pointer to the component to extract the named virtual function.
Returns:
Function pointer relating to the passed in record key, or NULL upon error.

Definition at line 789 of file poldiff.c.

References diff, poldiff_component_record_t, and poldiff_get_item_stats_fn_t.

Referenced by print_rule_diffs().

00790 {
00791         if (!diff) {
00792                 errno = EINVAL;
00793                 return NULL;
00794         }
00795         return diff->get_stats;
00796 }

poldiff_get_result_items_fn_t poldiff_component_record_get_results_fn const poldiff_component_record_t diff  ) 
 

Get the function that will return the results from a poldiff_component_record_t.

Parameters:
diff Pointer to the component to extract the named virtual function.
Returns:
Function pointer relating to the passed in record key, or NULL upon error.

Definition at line 798 of file poldiff.c.

References diff, poldiff_component_record_t, and poldiff_get_result_items_fn_t.

Referenced by print_rule_diffs(), result_item_create_from_flag(), and result_item_create_terules_from_flag().

00799 {
00800         if (!diff) {
00801                 errno = EINVAL;
00802                 return NULL;
00803         }
00804         return diff->get_results;
00805 }

const char* poldiff_component_record_get_label const poldiff_component_record_t diff  ) 
 

Get the function that will return the label from a poldiff_component_record_t.

This label describes the policy component (e.g., "attribute" or "AVrule dontaudit").

Parameters:
diff Pointer to the component to extract named the label.
Returns:
Label describing the policy component record. Do not modify this string.

Definition at line 807 of file poldiff.c.

References diff, and poldiff_component_record_t.

Referenced by result_item_create_from_flag(), and result_item_create_terules_from_flag().

00808 {
00809         if (!diff) {
00810                 errno = EINVAL;
00811                 return NULL;
00812         }
00813         return diff->item_name;
00814 }


Variable Documentation

const poldiff_component_record_t component_records[] [static]
 

Definition at line 56 of file poldiff.c.

Referenced by poldiff_get_component_record(), poldiff_get_stats(), and poldiff_run().