range_internal.h File Reference


Detailed Description

Protected interface for range differences.

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

Go to the source code of this file.


Functions

poldiff_range_trange_create (const poldiff_t *diff, const qpol_mls_range_t *orig_range, const qpol_mls_range_t *mod_range, poldiff_form_e form)
 Allocate and return a poldiff_range_t object.
void range_destroy (poldiff_range_t **range)
 Deallocate all space for a range, including the pointer itself.
int range_deep_diff (poldiff_t *diff, poldiff_range_t *range)
 Calculate the differences between two ranges (that are stored within the poldiff_range_t object).

Function Documentation

poldiff_range_t* range_create const poldiff_t diff,
const qpol_mls_range_t orig_range,
const qpol_mls_range_t mod_range,
poldiff_form_e  form
 

Allocate and return a poldiff_range_t object.

This will fill in the orig_range and mod_range strings. If the form is modified, then this will allocate the levels vector but leave it empty. Otherwise the levels vector will be filled with the levels that were added/removed.

Parameters:
diff Diff object containing policies.
orig_range Range from original policy, or NULL if there is no original range.
mod_range Range from modified policy, or NULL if there is no modified range.
form Form of the range.
Returns:
An initialized range, or NULL upon error. Caller must call range_destroy() upon the returned value.

Definition at line 183 of file range_diff.c.

References apol_mls_level_get_cats(), apol_mls_level_get_sens(), apol_mls_level_t, apol_mls_range_create_from_qpol_mls_range(), apol_mls_range_get_levels(), apol_mls_range_t, apol_policy_t, apol_str_strdup(), apol_vector_append(), apol_vector_create(), apol_vector_create_from_vector(), apol_vector_create_with_capacity(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, diff, ERR, level_free(), poldiff::mod_pol, poldiff::orig_pol, POLDIFF_FORM_ADDED, POLDIFF_FORM_REMOVED, poldiff_level_t, poldiff_range_t, poldiff_t, and range_destroy().

Referenced by range_trans_deep_diff(), range_trans_new_diff(), and user_deep_diff_ranges().

00185 {
00186         poldiff_range_t *pr = NULL;
00187         apol_policy_t *p;
00188         apol_mls_range_t *range;
00189         apol_vector_t *levels = NULL;
00190         poldiff_level_t *pl = NULL;
00191         size_t i;
00192         int retval = -1;
00193         if ((pr = calloc(1, sizeof(*pr))) == NULL || (pr->levels = apol_vector_create(level_free)) == NULL) {
00194                 ERR(diff, "%s", strerror(errno));
00195                 goto cleanup;
00196         }
00197         if (orig_range != NULL && (pr->orig_range = apol_mls_range_create_from_qpol_mls_range(diff->orig_pol, orig_range)) == NULL) {
00198                 goto cleanup;
00199         }
00200         if (mod_range != NULL && (pr->mod_range = apol_mls_range_create_from_qpol_mls_range(diff->mod_pol, mod_range)) == NULL) {
00201                 goto cleanup;
00202         }
00203         if (form == POLDIFF_FORM_ADDED || form == POLDIFF_FORM_ADD_TYPE) {
00204                 p = diff->mod_pol;
00205                 range = pr->mod_range;
00206         } else if (form == POLDIFF_FORM_REMOVED || form == POLDIFF_FORM_REMOVE_TYPE) {
00207                 p = diff->orig_pol;
00208                 range = pr->orig_range;
00209         } else if (form == POLDIFF_FORM_MODIFIED) {
00210                 /* don't fill in the range's levels here */
00211                 return pr;
00212         } else {
00213                 /* should never get here */
00214                 assert(0);
00215                 return pr;
00216         }
00217         if ((levels = apol_mls_range_get_levels(p, range)) == NULL) {
00218                 goto cleanup;
00219         }
00220         for (i = 0; i < apol_vector_get_size(levels); i++) {
00221                 apol_mls_level_t *l = apol_vector_get_element(levels, i);
00222                 const char *sens = apol_mls_level_get_sens(l);
00223                 const apol_vector_t *cats = apol_mls_level_get_cats(l);
00224                 if ((pl = calloc(1, sizeof(*pl))) == NULL ||
00225                     (pl->name = strdup(sens)) == NULL || (pl->unmodified_cats = apol_vector_create_with_capacity(1, free)) == NULL)
00226                 {
00227                         ERR(diff, "%s", strerror(errno));
00228                         goto cleanup;
00229                 }
00230                 if (form == POLDIFF_FORM_ADDED) {
00231                         if ((pl->added_cats = apol_vector_create_from_vector(cats, apol_str_strdup, NULL, free)) == NULL ||
00232                             (pl->removed_cats = apol_vector_create_with_capacity(1, free)) == NULL) {
00233                                 ERR(diff, "%s", strerror(errno));
00234                                 goto cleanup;
00235                         }
00236                 } else if (form == POLDIFF_FORM_REMOVED) {
00237                         if ((pl->added_cats = apol_vector_create_with_capacity(1, free)) == NULL ||
00238                             (pl->removed_cats = apol_vector_create_from_vector(cats, apol_str_strdup, NULL, free)) == NULL) {
00239                                 ERR(diff, "%s", strerror(errno));
00240                                 goto cleanup;
00241                         }
00242                 }
00243                 if (apol_vector_append(pr->levels, pl) < 0) {
00244                         ERR(diff, "%s", strerror(errno));
00245                         goto cleanup;
00246                 }
00247                 pl = NULL;
00248         }
00249         retval = 0;
00250       cleanup:
00251         apol_vector_destroy(&levels);
00252         if (retval != 0) {
00253                 level_free(pl);
00254                 range_destroy(&pr);
00255                 return NULL;
00256         }
00257         return pr;
00258 }

void range_destroy poldiff_range_t **  range  ) 
 

Deallocate all space for a range, including the pointer itself.

Afterwards set the pointer to NULL.

Parameters:
range Reference to a range to destroy.

Definition at line 260 of file range_diff.c.

References apol_mls_range_destroy(), apol_vector_destroy(), and poldiff_range_t.

Referenced by range_create(), range_trans_deep_diff(), range_trans_free(), user_deep_diff_ranges(), and user_free().

00261 {
00262         if (range != NULL && *range != NULL) {
00263                 apol_mls_range_destroy(&(*range)->orig_range);
00264                 apol_mls_range_destroy(&(*range)->mod_range);
00265                 apol_vector_destroy(&(*range)->levels);
00266                 apol_vector_destroy(&(*range)->min_added_cats);
00267                 apol_vector_destroy(&(*range)->min_removed_cats);
00268                 apol_vector_destroy(&(*range)->min_unmodified_cats);
00269                 free(*range);
00270                 *range = NULL;
00271         }
00272 }

int range_deep_diff poldiff_t diff,
poldiff_range_t range
 

Calculate the differences between two ranges (that are stored within the poldiff_range_t object).

This involves two things: changes in the expanded levels, and changes to minimum category sets. If differences are found then the range's levels vector will be filled with those differences.

Parameters:
diff Diff object containing policies.
range Range object to diff.
Returns:
Greater than zero if a diff was found, zero if none found, less than zero for errors.

Definition at line 317 of file range_diff.c.

References apol_mls_level_get_cats(), apol_mls_level_get_sens(), apol_mls_level_t, apol_mls_range_get_levels(), apol_mls_range_get_low(), apol_vector_append(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort(), apol_vector_t, diff, level_create_from_apol_mls_level(), level_deep_diff_apol_mls_levels(), level_deep_diff_cats(), level_free(), poldiff_range::levels, poldiff_range::min_added_cats, poldiff_range::min_removed_cats, poldiff_range::min_unmodified_cats, poldiff::mod_pol, poldiff_range::mod_range, poldiff::orig_pol, poldiff_range::orig_range, POLDIFF_FORM_ADDED, POLDIFF_FORM_REMOVED, poldiff_level_t, poldiff_range_t, poldiff_t, range_comp(), and range_comp_alphabetize().

Referenced by range_trans_deep_diff(), and user_deep_diff_ranges().

00318 {
00319         apol_vector_t *orig_levels = NULL, *mod_levels = NULL;
00320         apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL;
00321         apol_mls_level_t *l1, *l2;
00322         poldiff_level_t *pl1, *pl2;
00323         size_t i, j;
00324         int retval = -1, differences_found = 0, compval;
00325         if ((orig_levels = apol_mls_range_get_levels(diff->orig_pol, range->orig_range)) == NULL ||
00326             (mod_levels = apol_mls_range_get_levels(diff->mod_pol, range->mod_range)) == NULL) {
00327                 goto cleanup;
00328         }
00329         apol_vector_sort(orig_levels, range_comp_alphabetize, NULL);
00330         apol_vector_sort(mod_levels, range_comp_alphabetize, NULL);
00331         for (i = j = 0; i < apol_vector_get_size(orig_levels);) {
00332                 if (j >= apol_vector_get_size(mod_levels))
00333                         break;
00334                 l1 = (apol_mls_level_t *) apol_vector_get_element(orig_levels, i);
00335                 l2 = (apol_mls_level_t *) apol_vector_get_element(mod_levels, j);
00336                 pl1 = pl2 = NULL;
00337                 const char *sens1 = apol_mls_level_get_sens(l1);
00338                 const char *sens2 = apol_mls_level_get_sens(l2);
00339                 compval = strcmp(sens1, sens2);
00340                 if (compval < 0) {
00341                         if ((pl1 = level_create_from_apol_mls_level(l1, POLDIFF_FORM_REMOVED)) == NULL
00342                             || apol_vector_append(range->levels, pl1) < 0) {
00343                                 level_free(pl1);
00344                                 goto cleanup;
00345                         }
00346                         differences_found = 1;
00347                         i++;
00348                 } else if (compval > 0) {
00349                         if ((pl2 = level_create_from_apol_mls_level(l2, POLDIFF_FORM_ADDED)) == NULL
00350                             || apol_vector_append(range->levels, pl2) < 0) {
00351                                 level_free(pl2);
00352                                 goto cleanup;
00353                         }
00354                         differences_found = 1;
00355                         j++;
00356                 } else {
00357                         if (level_deep_diff_apol_mls_levels(diff, l1, l2, &pl1, &pl2) < 0) {
00358                                 goto cleanup;
00359                         }
00360                         assert(pl2 == NULL);
00361                         if (pl1 != NULL) {
00362                                 if (apol_vector_append(range->levels, pl1) < 0) {
00363                                         level_free(pl1);
00364                                         goto cleanup;
00365                                 }
00366                                 differences_found = 1;
00367                         }
00368                         i++;
00369                         j++;
00370                 }
00371         }
00372         for (; i < apol_vector_get_size(orig_levels); i++) {
00373                 l1 = (apol_mls_level_t *) apol_vector_get_element(orig_levels, i);
00374                 if ((pl1 = level_create_from_apol_mls_level(l1, POLDIFF_FORM_REMOVED)) == NULL
00375                     || apol_vector_append(range->levels, pl1) < 0) {
00376                         level_free(pl1);
00377                         goto cleanup;
00378                 }
00379                 differences_found = 1;
00380         }
00381         for (; j < apol_vector_get_size(mod_levels); j++) {
00382                 l2 = (apol_mls_level_t *) apol_vector_get_element(mod_levels, j);
00383                 if ((pl2 = level_create_from_apol_mls_level(l2, POLDIFF_FORM_ADDED)) == NULL
00384                     || apol_vector_append(range->levels, pl2) < 0) {
00385                         level_free(pl2);
00386                         goto cleanup;
00387                 }
00388                 differences_found = 1;
00389         }
00390         /* now check minimum category sets */
00391         const apol_mls_level_t *low1 = apol_mls_range_get_low(range->orig_range);
00392         const apol_vector_t *cats1 = apol_mls_level_get_cats(low1);
00393         const apol_mls_level_t *low2 = apol_mls_range_get_low(range->mod_range);
00394         const apol_vector_t *cats2 = apol_mls_level_get_cats(low2);
00395         compval = level_deep_diff_cats(diff, cats1, cats2, &added, &removed, &unmodified);
00396         if (compval < 0) {
00397                 goto cleanup;
00398         } else if (compval > 0) {
00399                 differences_found = 1;
00400                 range->min_added_cats = added;
00401                 range->min_removed_cats = removed;
00402                 range->min_unmodified_cats = unmodified;
00403                 added = NULL;
00404                 removed = NULL;
00405                 unmodified = NULL;
00406         }
00407         if (differences_found) {
00408                 apol_vector_sort(range->levels, range_comp, diff);
00409                 retval = 1;
00410         } else {
00411                 retval = 0;
00412         }
00413       cleanup:
00414         apol_vector_destroy(&orig_levels);
00415         apol_vector_destroy(&mod_levels);
00416         apol_vector_destroy(&added);
00417         apol_vector_destroy(&removed);
00418         apol_vector_destroy(&unmodified);
00419         return retval;
00420 }