Jason Tang jtang@tresys.com
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 level_diff.c.
#include <config.h>
#include "poldiff_internal.h"
#include <apol/util.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
Go to the source code of this file.
Classes | |
| struct | poldiff_level_summary |
Functions | |
| void | poldiff_level_get_stats (const poldiff_t *diff, size_t stats[5]) |
| Get an array of statistics for the number of differences of each form for levels. | |
| const apol_vector_t * | poldiff_get_level_vector (const poldiff_t *diff) |
| Get the vector of level differences from the level difference summary. | |
| char * | poldiff_level_to_string (const poldiff_t *diff, const void *level) |
| Obtain a newly allocated string representation of a difference in a level. | |
| char * | poldiff_level_to_string_brief (const poldiff_t *diff, const poldiff_level_t *level) |
| Allocate and return a string rendering of a poldiff_level_t, suitable for embedding within some other component's to_string function (e.g., a user's default level). | |
| const char * | poldiff_level_get_name (const poldiff_level_t *level) |
| Get the name of the level (i.e., the sensitivity) from a level diff. | |
| poldiff_form_e | poldiff_level_get_form (const void *level) |
| Get the form of difference from a level diff. | |
| const apol_vector_t * | poldiff_level_get_added_cats (const poldiff_level_t *level) |
| Get a vector of categories added to the level. | |
| const apol_vector_t * | poldiff_level_get_removed_cats (const poldiff_level_t *level) |
| Get a vector of categories removed from the level. | |
| const apol_vector_t * | poldiff_level_get_unmodified_cats (const poldiff_level_t *level) |
| Get a vector of unmodified categories from the level. | |
| poldiff_level_summary_t * | level_create (void) |
| Allocate and return a new poldiff_level_summary_t object. | |
| void | level_destroy (poldiff_level_summary_t **ls) |
| Deallocate all space associated with a poldiff_level_summary_t object, including the pointer itself. | |
| int | level_reset (poldiff_t *diff) |
| Reset the state of all level differences. | |
| int | level_name_comp (const void *x, const void *y, void *arg) |
| Comparison function for two levels from the same policy. | |
| apol_vector_t * | level_get_items (poldiff_t *diff, const apol_policy_t *policy) |
| Get a vector of all levels from the given policy, sorted by name. | |
| int | level_comp (const void *x, const void *y, const poldiff_t *diff) |
| Compare two qpol_level_t objects, determining if they have the same level name or not. | |
| poldiff_level_t * | make_diff (const poldiff_t *diff, poldiff_form_e form, const char *name) |
| Allocate and return a new level difference object. | |
| apol_vector_t * | level_get_cats (const poldiff_t *diff, const apol_policy_t *p, const qpol_level_t *level) |
| Given a level, return a vector of its allowed categories (in the form of strings). | |
| int | level_new_diff (poldiff_t *diff, poldiff_form_e form, const void *item) |
| Create, initialize, and insert a new semantic difference entry for a level. | |
| int | level_cat_comp (const void *a, const void *b, void *data) |
| Comparison function for two category names from the same policy. | |
| int | level_deep_diff (poldiff_t *diff, const void *x, const void *y) |
| Compute the semantic difference of two levels for which the compare callback returns 0. | |
| poldiff_level_t * | level_create_from_apol_mls_level (const apol_mls_level_t *level, poldiff_form_e form) |
| Allocate and return a poldiff_level_t object. | |
| void | level_free (void *elem) |
| Deallocate all space associated with a poldiff_level_t, including the pointer itself. | |
| int | level_deep_diff_apol_mls_levels (poldiff_t *diff, const apol_mls_level_t *level1, const apol_mls_level_t *level2, poldiff_level_t **orig_pl, poldiff_level_t **mod_pl) |
| Perform a deep diff of two levels. | |
| int | level_deep_diff_cats (poldiff_t *diff, const apol_vector_t *v1, const apol_vector_t *v2, apol_vector_t **added, apol_vector_t **removed, apol_vector_t **unmodified) |
| Calculate the differences between two sorted vectors of category names. | |
|
||||||||||||
|
Get an array of statistics for the number of differences of each form for levels.
Definition at line 43 of file level_diff.c. References diff, ERR, poldiff::level_diffs, poldiff_level_summary::num_added, poldiff_level_summary::num_modified, poldiff_level_summary::num_removed, and poldiff_t. 00044 {
00045 if (diff == NULL || stats == NULL) {
00046 ERR(diff, "%s", strerror(EINVAL));
00047 errno = EINVAL;
00048 return;
00049 }
00050 stats[0] = diff->level_diffs->num_added;
00051 stats[1] = diff->level_diffs->num_removed;
00052 stats[2] = diff->level_diffs->num_modified;
00053 stats[3] = 0;
00054 stats[4] = 0;
00055 }
|
|
|
Get the vector of level differences from the level difference summary.
Definition at line 57 of file level_diff.c. References apol_vector_t, diff, poldiff_level_summary::diffs, poldiff::level_diffs, and poldiff_t. Referenced by build_level_vecs(). 00058 {
00059 if (diff == NULL) {
00060 errno = EINVAL;
00061 return NULL;
00062 }
00063 return diff->level_diffs->diffs;
00064 }
|
|
||||||||||||
|
Obtain a newly allocated string representation of a difference in a level.
Definition at line 66 of file level_diff.c. References poldiff_level::added_cats, apol_str_append(), apol_str_appendf(), apol_vector_get_element(), apol_vector_get_size(), diff, ERR, poldiff_level::form, level, poldiff_level::name, POLDIFF_FORM_ADDED, POLDIFF_FORM_MODIFIED, POLDIFF_FORM_REMOVED, poldiff_level_t, poldiff_t, and poldiff_level::removed_cats. 00067 {
00068 poldiff_level_t *l = (poldiff_level_t *) level;
00069 size_t num_added, num_removed, len = 0, i;
00070 char *s = NULL, *cat;
00071 if (diff == NULL || level == NULL) {
00072 ERR(diff, "%s", strerror(EINVAL));
00073 errno = EINVAL;
00074 return NULL;
00075 }
00076 num_added = apol_vector_get_size(l->added_cats);
00077 num_removed = apol_vector_get_size(l->removed_cats);
00078 switch (l->form) {
00079 case POLDIFF_FORM_ADDED:
00080 {
00081 if (apol_str_appendf(&s, &len, "+ %s", l->name) < 0) {
00082 break;
00083 }
00084 return s;
00085 }
00086 case POLDIFF_FORM_REMOVED:
00087 {
00088 if (apol_str_appendf(&s, &len, "- %s", l->name) < 0) {
00089 break;
00090 }
00091 return s;
00092 }
00093 case POLDIFF_FORM_MODIFIED:
00094 {
00095 if (apol_str_appendf(&s, &len, "* %s (", l->name) < 0) {
00096 break;
00097 }
00098 if (num_added > 0) {
00099 if (apol_str_appendf(&s, &len, "%zd Added %s", num_added, (num_added == 1 ? "Category" : "Categories")) < 0) {
00100 break;
00101 }
00102 }
00103 if (num_removed > 0) {
00104 if (apol_str_appendf
00105 (&s, &len, "%s%zd Removed %s", (num_added > 0 ? ", " : ""), num_removed,
00106 (num_removed == 1 ? "Category" : "Categories")) < 0) {
00107 break;
00108 }
00109 }
00110 if (apol_str_append(&s, &len, ")\n") < 0) {
00111 break;
00112 }
00113 for (i = 0; i < apol_vector_get_size(l->added_cats); i++) {
00114 cat = (char *)apol_vector_get_element(l->added_cats, i);
00115 if (apol_str_appendf(&s, &len, "\t+ %s\n", cat) < 0) {
00116 goto err;
00117 }
00118 }
00119 for (i = 0; i < apol_vector_get_size(l->removed_cats); i++) {
00120 cat = (char *)apol_vector_get_element(l->removed_cats, i);
00121 if (apol_str_appendf(&s, &len, "\t- %s\n", cat) < 0) {
00122 goto err;
00123 }
00124 }
00125 return s;
00126 }
00127 default:
00128 {
00129 ERR(diff, "%s", strerror(ENOTSUP));
00130 errno = ENOTSUP;
00131 return NULL;
00132 }
00133 }
00134 err:
00135 /* if this is reached then an error occurred */
00136 free(s);
00137 ERR(diff, "%s", strerror(ENOMEM));
00138 errno = ENOMEM;
00139 return NULL;
00140 }
|
|
||||||||||||
|
Allocate and return a string rendering of a poldiff_level_t, suitable for embedding within some other component's to_string function (e.g., a user's default level).
Definition at line 142 of file level_diff.c. References poldiff_level::added_cats, apol_str_append(), apol_str_appendf(), apol_vector_get_element(), apol_vector_get_size(), diff, ERR, poldiff_level::form, level, poldiff_level::name, POLDIFF_FORM_ADDED, POLDIFF_FORM_MODIFIED, POLDIFF_FORM_REMOVED, poldiff_level_t, poldiff_t, poldiff_level::removed_cats, and poldiff_level::unmodified_cats. Referenced by poldiff_range_to_string_brief(), result_item_print_modified_range(), result_item_user_print_modified(), and user_to_modified_string(). 00143 {
00144 char *s = NULL, t, *cat, *sep = "";
00145 int show_cat_sym = 0;
00146 size_t len = 0, i;
00147 switch (level->form) {
00148 case POLDIFF_FORM_ADDED:
00149 t = '+';
00150 break;
00151 case POLDIFF_FORM_REMOVED:
00152 t = '-';
00153 break;
00154 case POLDIFF_FORM_MODIFIED:
00155 t = '*';
00156 show_cat_sym = 1;
00157 break;
00158 default:
00159 /* don't show unmodified levels */
00160 if ((s = strdup("")) == NULL) {
00161 ERR(diff, "%s", strerror(errno));
00162 return NULL;
00163 }
00164 return s;
00165 }
00166 if (apol_str_appendf(&s, &len, "%c %s", t, level->name) < 0) {
00167 ERR(diff, "%s", strerror(errno));
00168 return NULL;
00169 }
00170 if ((level->unmodified_cats != NULL && apol_vector_get_size(level->unmodified_cats) > 0) ||
00171 (level->added_cats != NULL && apol_vector_get_size(level->added_cats) > 0) ||
00172 (level->removed_cats != NULL && apol_vector_get_size(level->removed_cats) > 0)) {
00173 if (apol_str_append(&s, &len, " : ") < 0) {
00174 ERR(diff, "%s", strerror(errno));
00175 return NULL;
00176 }
00177 for (i = 0; level->unmodified_cats != NULL && i < apol_vector_get_size(level->unmodified_cats); i++) {
00178 cat = apol_vector_get_element(level->unmodified_cats, i);
00179 if (apol_str_appendf(&s, &len, "%s%s", sep, cat) < 0) {
00180 ERR(diff, "%s", strerror(errno));
00181 return NULL;
00182 }
00183 sep = ",";
00184 }
00185 for (i = 0; level->added_cats != NULL && i < apol_vector_get_size(level->added_cats); i++) {
00186 cat = apol_vector_get_element(level->added_cats, i);
00187 if (apol_str_appendf(&s, &len, "%s%s%s", sep, (show_cat_sym ? "+" : ""), cat) < 0) {
00188 ERR(diff, "%s", strerror(errno));
00189 return NULL;
00190 }
00191 sep = ",";
00192 }
00193 for (i = 0; level->removed_cats != NULL && i < apol_vector_get_size(level->removed_cats); i++) {
00194 cat = apol_vector_get_element(level->removed_cats, i);
00195 if (apol_str_appendf(&s, &len, "%s%s%s", sep, (show_cat_sym ? "-" : ""), cat) < 0) {
00196 ERR(diff, "%s", strerror(errno));
00197 return NULL;
00198 }
00199 sep = ",";
00200 }
00201 }
00202 if (apol_str_append(&s, &len, "\n") < 0) {
00203 ERR(diff, "%s", strerror(errno));
00204 return NULL;
00205 }
00206 return s;
00207 }
|
|
|
Get the name of the level (i.e., the sensitivity) from a level diff.
Definition at line 209 of file level_diff.c. References level, poldiff_level::name, and poldiff_level_t. Referenced by level_to_string(), and modified_mls_range_to_string(). 00210 {
00211 if (level == NULL) {
00212 errno = EINVAL;
00213 return NULL;
00214 }
00215
00216 return level->name;
00217 }
|
|
|
Get the form of difference from a level diff.
Definition at line 219 of file level_diff.c. References poldiff_level::form, level, poldiff_form_e, and poldiff_level_t. Referenced by mls_user_to_string(), modified_mls_range_to_string(), result_item_print_modified_range(), and result_item_user_print_modified(). 00220 {
00221 if (level == NULL) {
00222 errno = EINVAL;
00223 return POLDIFF_FORM_NONE;
00224 }
00225
00226 return ((const poldiff_level_t *)level)->form;
00227 }
|
|
|
Get a vector of categories added to the level. These will be sorted in the same order as given by the modified policy. If the level was added by the modified policy then this vector will hold all of the categories.
Definition at line 229 of file level_diff.c. References poldiff_level::added_cats, apol_vector_t, level, and poldiff_level_t. Referenced by level_to_string(), and modified_mls_range_to_string(). 00230 {
00231 if (level == NULL) {
00232 errno = EINVAL;
00233 return NULL;
00234 }
00235 return level->added_cats;
00236 }
|
|
|
Get a vector of categories removed from the level. These will be sorted in the same order as given by the original policy. If the level was removed by the modified policy then this vector will hold all of the categories.
Definition at line 238 of file level_diff.c. References apol_vector_t, level, poldiff_level_t, and poldiff_level::removed_cats. Referenced by level_to_string(), and modified_mls_range_to_string(). 00239 {
00240 if (level == NULL) {
00241 errno = EINVAL;
00242 return NULL;
00243 }
00244
00245 return level->removed_cats;
00246 }
|
|
|
Get a vector of unmodified categories from the level. These will be sorted in the same order as given by the original policy.
Definition at line 248 of file level_diff.c. References apol_vector_t, level, poldiff_level_t, and poldiff_level::unmodified_cats. Referenced by modified_mls_range_to_string(). 00249 {
00250 if (level == NULL) {
00251 errno = EINVAL;
00252 return NULL;
00253 }
00254
00255 return level->unmodified_cats;
00256 }
|
|
|
Allocate and return a new poldiff_level_summary_t object.
Definition at line 258 of file level_diff.c. References apol_vector_create(), poldiff_level_summary::diffs, level_destroy(), level_free(), and poldiff_level_summary_t. Referenced by level_reset(), and poldiff_create(). 00259 {
00260 poldiff_level_summary_t *ls = calloc(1, sizeof(poldiff_level_summary_t));
00261 if (ls == NULL)
00262 return NULL;
00263 if ((ls->diffs = apol_vector_create(level_free)) == NULL) {
00264 level_destroy(&ls);
00265 return NULL;
00266 }
00267 return ls;
00268 }
|
|
|
Deallocate all space associated with a poldiff_level_summary_t object, including the pointer itself. If the pointer is already NULL then do nothing.
Definition at line 270 of file level_diff.c. References apol_vector_destroy(), and poldiff_level_summary_t. Referenced by level_create(), level_reset(), and poldiff_destroy(). 00271 {
00272 if (ls == NULL || *ls == NULL)
00273 return;
00274 apol_vector_destroy(&(*ls)->diffs);
00275 free(*ls);
00276 *ls = NULL;
00277 }
|
|
|
Reset the state of all level differences.
Definition at line 279 of file level_diff.c. References diff, ERR, level_create(), level_destroy(), poldiff::level_diffs, and poldiff_t. 00280 {
00281 int error = 0;
00282
00283 if (diff == NULL) {
00284 ERR(diff, "%s", strerror(EINVAL));
00285 errno = EINVAL;
00286 return -1;
00287 }
00288
00289 level_destroy(&diff->level_diffs);
00290 diff->level_diffs = level_create();
00291 if (diff->level_diffs == NULL) {
00292 error = errno;
00293 ERR(diff, "%s", strerror(error));
00294 errno = error;
00295 return -1;
00296 }
00297
00298 return 0;
00299 }
|
|
||||||||||||||||
|
Comparison function for two levels from the same policy.
Definition at line 304 of file level_diff.c. References apol_policy_get_qpol(), apol_policy_t, qpol_level_get_name(), qpol_level_t, and qpol_policy_t. Referenced by level_get_items(). 00305 {
00306 const qpol_level_t *s1 = x;
00307 const qpol_level_t *s2 = y;
00308 apol_policy_t *p = arg;
00309 qpol_policy_t *q = apol_policy_get_qpol(p);
00310 const char *name1, *name2;
00311
00312 if (qpol_level_get_name(q, s1, &name1) < 0 || qpol_level_get_name(q, s2, &name2) < 0)
00313 return 0;
00314 return strcmp(name1, name2);
00315 }
|
|
||||||||||||
|
Get a vector of all levels from the given policy, sorted by name.
Definition at line 317 of file level_diff.c. References apol_policy_get_qpol(), apol_policy_t, apol_vector_create_from_iter(), apol_vector_sort(), apol_vector_t, diff, ERR, level_name_comp(), poldiff_t, qpol_iterator_destroy(), qpol_iterator_t, qpol_policy_get_level_iter(), and qpol_policy_t. 00318 {
00319 qpol_iterator_t *iter = NULL;
00320 apol_vector_t *v = NULL;
00321 qpol_policy_t *q = apol_policy_get_qpol(policy);
00322 int error = 0;
00323 if (qpol_policy_get_level_iter(q, &iter) < 0) {
00324 return NULL;
00325 }
00326 v = apol_vector_create_from_iter(iter, NULL);
00327 if (v == NULL) {
00328 error = errno;
00329 ERR(diff, "%s", strerror(error));
00330 qpol_iterator_destroy(&iter);
00331 errno = error;
00332 return NULL;
00333 }
00334 qpol_iterator_destroy(&iter);
00335 apol_vector_sort(v, level_name_comp, (void *)policy);
00336 return v;
00337 }
|
|
||||||||||||||||
|
Compare two qpol_level_t objects, determining if they have the same level name or not.
Definition at line 339 of file level_diff.c. References diff, poldiff::mod_qpol, poldiff::orig_qpol, poldiff_t, qpol_level_get_name(), and qpol_level_t. 00340 {
00341 const qpol_level_t *l1 = x;
00342 const qpol_level_t *l2 = y;
00343 const char *name1, *name2;
00344 if (qpol_level_get_name(diff->orig_qpol, l1, &name1) < 0 || qpol_level_get_name(diff->mod_qpol, l2, &name2) < 0) {
00345 return 0;
00346 }
00347 return strcmp(name1, name2);
00348 }
|
|
||||||||||||||||
|
Allocate and return a new level difference object.
Definition at line 361 of file level_diff.c. References apol_vector_create(), diff, ERR, poldiff_user::form, level_free(), poldiff_level_t, and poldiff_t. 00362 {
00363 poldiff_level_t *pl;
00364 int error;
00365 if ((pl = calloc(1, sizeof(*pl))) == NULL || (pl->name = strdup(name)) == NULL ||
00366 (pl->added_cats = apol_vector_create(free)) == NULL ||
00367 (pl->removed_cats = apol_vector_create(free)) == NULL || (pl->unmodified_cats = apol_vector_create(free)) == NULL) {
00368 error = errno;
00369 level_free(pl);
00370 ERR(diff, "%s", strerror(error));
00371 errno = error;
00372 return NULL;
00373 }
00374 pl->form = form;
00375 return pl;
00376 }
|
|
||||||||||||||||
|
Given a level, return a vector of its allowed categories (in the form of strings). These will be sorted in policy order.
Definition at line 390 of file level_diff.c. References apol_policy_get_qpol(), apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_t, diff, ERR, level, poldiff_t, qpol_cat_get_name(), qpol_cat_t, qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_level_get_cat_iter(), and qpol_policy_t. Referenced by level_deep_diff(), and level_new_diff(). 00391 {
00392 qpol_iterator_t *iter = NULL;
00393 const qpol_cat_t *cat;
00394 const char *cat_name;
00395 apol_vector_t *v = NULL;
00396 qpol_policy_t *q = apol_policy_get_qpol(p);
00397 int retval = -1, error = 0;
00398
00399 if ((v = apol_vector_create(NULL)) == NULL) {
00400 ERR(diff, "%s", strerror(errno));
00401 goto cleanup;
00402 }
00403 if (qpol_level_get_cat_iter(q, level, &iter) < 0) {
00404 goto cleanup;
00405 }
00406 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00407 if (qpol_iterator_get_item(iter, (void **)&cat) < 0 || qpol_cat_get_name(q, cat, &cat_name)) {
00408 error = errno;
00409 goto cleanup;
00410 }
00411 if (apol_vector_append(v, (void *)cat_name) < 0) {
00412 error = errno;
00413 ERR(diff, "%s", strerror(error));
00414 goto cleanup;
00415 }
00416 }
00417
00418 retval = 0;
00419 cleanup:
00420 qpol_iterator_destroy(&iter);
00421 if (retval < 0) {
00422 apol_vector_destroy(&v);
00423 errno = error;
00424 return NULL;
00425 }
00426 return v;
00427 }
|
|
||||||||||||||||
|
Create, initialize, and insert a new semantic difference entry for a level.
Definition at line 429 of file level_diff.c. References poldiff_level::added_cats, apol_policy_t, apol_str_strdup(), apol_vector_append(), apol_vector_create_from_vector(), apol_vector_destroy(), apol_vector_t, diff, poldiff_level_summary::diffs, ERR, poldiff::level_diffs, level_free(), level_get_cats(), make_diff(), poldiff::mod_pol, poldiff::mod_qpol, poldiff_level_summary::num_added, poldiff_level_summary::num_removed, poldiff::orig_pol, poldiff::orig_qpol, poldiff_level_t, poldiff_t, qpol_level_get_name(), qpol_level_t, qpol_policy_t, and poldiff_level::removed_cats. 00430 {
00431 const qpol_level_t *l = item;
00432 const char *name = NULL;
00433 poldiff_level_t *pl = NULL;
00434 apol_policy_t *p;
00435 qpol_policy_t *q;
00436 apol_vector_t *v = NULL;
00437 int error = 0, retval = -1;
00438 if (form == POLDIFF_FORM_ADDED) {
00439 p = diff->mod_pol;
00440 q = diff->mod_qpol;
00441 } else {
00442 p = diff->orig_pol;
00443 q = diff->orig_qpol;
00444 }
00445 if (qpol_level_get_name(q, l, &name) < 0 || (pl = make_diff(diff, form, name)) == NULL) {
00446 error = errno;
00447 goto cleanup;
00448 }
00449 if ((v = level_get_cats(diff, p, l)) == NULL) {
00450 error = errno;
00451 ERR(diff, "%s", strerror(error));
00452 goto cleanup;
00453 }
00454 if (form == POLDIFF_FORM_ADDED) {
00455 apol_vector_destroy(&pl->added_cats);
00456 if ((pl->added_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
00457 error = errno;
00458 ERR(diff, "%s", strerror(error));
00459 goto cleanup;
00460 }
00461 } else if (form == POLDIFF_FORM_REMOVED) {
00462 apol_vector_destroy(&pl->removed_cats);
00463 if ((pl->removed_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
00464 error = errno;
00465 ERR(diff, "%s", strerror(error));
00466 goto cleanup;
00467 }
00468 }
00469 if (apol_vector_append(diff->level_diffs->diffs, pl) < 0) {
00470 error = errno;
00471 ERR(diff, "%s", strerror(error));
00472 goto cleanup;
00473 }
00474 if (form == POLDIFF_FORM_ADDED) {
00475 diff->level_diffs->num_added++;
00476 } else {
00477 diff->level_diffs->num_removed++;
00478 }
00479 retval = 0;
00480 cleanup:
00481 apol_vector_destroy(&v);
00482 if (retval < 0) {
00483 level_free(pl);
00484 errno = error;
00485 }
00486 return retval;
00487 }
|
|
||||||||||||||||
|
Comparison function for two category names from the same policy.
Definition at line 499 of file level_diff.c. References qpol_cat_get_value(), qpol_cat_t, qpol_policy_get_cat_by_name(), and qpol_policy_t. Referenced by level_deep_diff(), and level_deep_diff_apol_mls_levels(). 00500 {
00501 const char *name1 = (const char *)a;
00502 const char *name2 = (const char *)b;
00503 qpol_policy_t *q = (qpol_policy_t *) data;
00504 const qpol_cat_t *cat1, *cat2;
00505 qpol_policy_get_cat_by_name(q, name1, &cat1);
00506 qpol_policy_get_cat_by_name(q, name2, &cat2);
00507 assert(cat1 != NULL && cat2 != NULL);
00508 uint32_t val1, val2;
00509 qpol_cat_get_value(q, cat1, &val1);
00510 qpol_cat_get_value(q, cat2, &val2);
00511 return val1 - val2;
00512 }
|
|
||||||||||||||||
|
Compute the semantic difference of two levels for which the compare callback returns 0. If a difference is found then allocate, initialize, and insert a new semantic difference entry for that level.
Definition at line 514 of file level_diff.c. References poldiff_level::added_cats, apol_str_strcmp(), apol_str_strdup(), apol_vector_append(), apol_vector_create_from_vector(), apol_vector_destroy(), apol_vector_sort(), apol_vector_t, diff, poldiff_level_summary::diffs, ERR, level_cat_comp(), level_deep_diff_cats(), poldiff::level_diffs, level_free(), level_get_cats(), make_diff(), poldiff::mod_pol, poldiff::mod_qpol, poldiff_level_summary::num_modified, poldiff::orig_pol, poldiff::orig_qpol, POLDIFF_FORM_MODIFIED, poldiff_level_t, poldiff_t, qpol_level_get_name(), qpol_level_t, poldiff_level::removed_cats, and poldiff_level::unmodified_cats. 00515 {
00516 const qpol_level_t *l1 = x;
00517 const qpol_level_t *l2 = y;
00518 apol_vector_t *v1 = NULL, *v2 = NULL;
00519 apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL;
00520 const char *name;
00521 poldiff_level_t *l = NULL;
00522 int retval = -1, error = 0, compval;
00523
00524 if (qpol_level_get_name(diff->orig_qpol, l1, &name) < 0 ||
00525 (v1 = level_get_cats(diff, diff->orig_pol, l1)) == NULL || (v2 = level_get_cats(diff, diff->mod_pol, l2)) == NULL) {
00526 error = errno;
00527 goto cleanup;
00528 }
00529 apol_vector_sort(v1, apol_str_strcmp, NULL);
00530 apol_vector_sort(v2, apol_str_strcmp, NULL);
00531 compval = level_deep_diff_cats(diff, v1, v2, &added, &removed, &unmodified);
00532 if (compval < 0) {
00533 error = errno;
00534 goto cleanup;
00535 } else if (compval > 0) {
00536 if ((l = make_diff(diff, POLDIFF_FORM_MODIFIED, name)) == NULL) {
00537 error = errno;
00538 goto cleanup;
00539 }
00540 apol_vector_destroy(&l->added_cats);
00541 apol_vector_destroy(&l->removed_cats);
00542 apol_vector_destroy(&l->unmodified_cats);
00543 if ((l->added_cats = apol_vector_create_from_vector(added, apol_str_strdup, NULL, free)) == NULL ||
00544 (l->removed_cats = apol_vector_create_from_vector(removed, apol_str_strdup, NULL, free)) == NULL ||
00545 (l->unmodified_cats = apol_vector_create_from_vector(unmodified, apol_str_strdup, NULL, free)) == NULL) {
00546 error = errno;
00547 ERR(diff, "%s", strerror(error));
00548 goto cleanup;
00549 }
00550 apol_vector_sort(l->removed_cats, level_cat_comp, diff->orig_qpol);
00551 apol_vector_sort(l->added_cats, level_cat_comp, diff->mod_qpol);
00552 apol_vector_sort(l->unmodified_cats, level_cat_comp, diff->orig_qpol);
00553 if (apol_vector_append(diff->level_diffs->diffs, l) < 0) {
00554 error = errno;
00555 ERR(diff, "%s", strerror(error));
00556 goto cleanup;
00557 }
00558 diff->level_diffs->num_modified++;
00559 }
00560 retval = 0;
00561 cleanup:
00562 apol_vector_destroy(&v1);
00563 apol_vector_destroy(&v2);
00564 apol_vector_destroy(&added);
00565 apol_vector_destroy(&removed);
00566 apol_vector_destroy(&unmodified);
00567 if (retval != 0) {
00568 level_free(l);
00569 }
00570 errno = error;
00571 return retval;
00572 }
|
|
||||||||||||
|
Allocate and return a poldiff_level_t object. If the form is added or removed, set that respective vector to be all of the categories from the given level.
Definition at line 574 of file level_diff.c. References apol_mls_level_get_cats(), apol_mls_level_get_sens(), apol_mls_level_t, apol_str_strdup(), apol_vector_create_from_vector(), apol_vector_create_with_capacity(), apol_vector_t, level, level_free(), and poldiff_level_t. Referenced by range_deep_diff(), and user_deep_diff_default_levels(). 00575 {
00576 const char *sens = apol_mls_level_get_sens(level);
00577 const apol_vector_t *cats = apol_mls_level_get_cats(level);
00578 poldiff_level_t *pl = NULL;
00579 apol_vector_t **target;
00580 if ((pl = calloc(1, sizeof(*pl))) == NULL ||
00581 (pl->name = strdup(sens)) == NULL || (pl->unmodified_cats = apol_vector_create_with_capacity(1, free)) == NULL) {
00582 level_free(pl);
00583 return NULL;;
00584 }
00585 pl->form = form;
00586 if (form == POLDIFF_FORM_ADDED) {
00587 if ((pl->removed_cats = apol_vector_create_with_capacity(1, free)) == NULL) {
00588 level_free(pl);
00589 return NULL;
00590 }
00591 target = &pl->added_cats;
00592 } else if (form == POLDIFF_FORM_REMOVED) {
00593 if ((pl->added_cats = apol_vector_create_with_capacity(1, free)) == NULL) {
00594 level_free(pl);
00595 return NULL;
00596 }
00597 target = &pl->removed_cats;
00598 } else {
00599 if ((pl->added_cats = apol_vector_create_with_capacity(1, free)) == NULL ||
00600 (pl->removed_cats = apol_vector_create_with_capacity(1, free)) == NULL) {
00601 level_free(pl);
00602 return NULL;
00603 }
00604 return pl;
00605 }
00606 if ((*target = apol_vector_create_from_vector(cats, apol_str_strdup, NULL, free)) == NULL) {
00607 level_free(pl);
00608 return NULL;
00609 }
00610 return pl;
00611 }
|
|
|
Deallocate all space associated with a poldiff_level_t, including the pointer itself.
Definition at line 613 of file level_diff.c. References poldiff_level::added_cats, apol_vector_destroy(), poldiff_level::name, poldiff_level_t, poldiff_level::removed_cats, and poldiff_level::unmodified_cats. Referenced by level_create(), level_create_from_apol_mls_level(), level_deep_diff(), level_deep_diff_apol_mls_levels(), level_new_diff(), make_diff(), range_create(), range_deep_diff(), user_deep_diff_default_levels(), and user_free(). 00614 {
00615 poldiff_level_t *s = elem;
00616 if (!elem)
00617 return;
00618 free(s->name);
00619 apol_vector_destroy(&s->added_cats);
00620 apol_vector_destroy(&s->removed_cats);
00621 apol_vector_destroy(&s->unmodified_cats);
00622 free(s);
00623 }
|
|
||||||||||||||||||||||||
|
Perform a deep diff of two levels. This will first compare the sensitivity names; if they match then it compares the vectors of category names. If the sensitivities do not match, then generate two poldiff_level_ts, one for the original level and one for modified level. If they do match then create just one poldiff_level_t and write it to orig_pl.
Definition at line 625 of file level_diff.c. References apol_mls_level_get_cats(), apol_mls_level_get_sens(), apol_mls_level_t, apol_str_strdup(), apol_vector_create_from_vector(), apol_vector_destroy(), apol_vector_sort(), apol_vector_t, diff, ERR, poldiff_level::form, level_cat_comp(), level_deep_diff_cats(), level_free(), make_diff(), poldiff::mod_qpol, poldiff::orig_qpol, POLDIFF_FORM_ADDED, POLDIFF_FORM_REMOVED, poldiff_level_t, poldiff_t, and poldiff_level::removed_cats. Referenced by range_deep_diff(), and user_deep_diff_default_levels(). 00627 {
00628 poldiff_level_t *u1 = NULL, *u2 = NULL;
00629 apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL;
00630 const char *sens1 = apol_mls_level_get_sens(level1);
00631 const apol_vector_t *cats1 = apol_mls_level_get_cats(level1);
00632 const char *sens2 = apol_mls_level_get_sens(level2);
00633 const apol_vector_t *cats2 = apol_mls_level_get_cats(level2);
00634 int retval = -1, compval;
00635
00636 *orig_pl = *mod_pl = NULL;
00637 if (strcmp(sens1, sens2) != 0) {
00638 /* sensitivities do not match, so don't check categories */
00639 if ((u1 = make_diff(diff, POLDIFF_FORM_REMOVED, sens1)) == NULL ||
00640 (u2 = make_diff(diff, POLDIFF_FORM_ADDED, sens2)) == NULL) {
00641 ERR(diff, "%s", strerror(errno));
00642 level_free(u1);
00643 level_free(u2);
00644 return -1;
00645 }
00646 apol_vector_destroy(&u1->removed_cats);
00647 apol_vector_destroy(&u2->added_cats);
00648 if ((u1->removed_cats = apol_vector_create_from_vector(cats1, apol_str_strdup, NULL, free)) == NULL ||
00649 (u2->added_cats = apol_vector_create_from_vector(cats2, apol_str_strdup, NULL, free)) == NULL) {
00650 ERR(diff, "%s", strerror(errno));
00651 level_free(u1);
00652 level_free(u2);
00653 return -1;
00654 }
00655 apol_vector_sort(u1->removed_cats, level_cat_comp, diff->orig_qpol);
00656 apol_vector_sort(u2->added_cats, level_cat_comp, diff->mod_qpol);
00657 *orig_pl = u1;
00658 *mod_pl = u2;
00659 return 0;
00660 }
00661
00662 compval = level_deep_diff_cats(diff, cats1, cats2, &added, &removed, &unmodified);
00663 if (compval < 0) {
00664 goto cleanup;
00665 } else if (compval > 0) {
00666 if ((u1 = calloc(1, sizeof(*u1))) == NULL || (u1->name = strdup(sens1)) == NULL ||
00667 (u1->added_cats = apol_vector_create_from_vector(added, apol_str_strdup, NULL, free)) == NULL ||
00668 (u1->removed_cats = apol_vector_create_from_vector(removed, apol_str_strdup, NULL, free)) == NULL ||
00669 (u1->unmodified_cats = apol_vector_create_from_vector(unmodified, apol_str_strdup, NULL, free)) == NULL) {
00670 ERR(diff, "%s", strerror(errno));
00671 level_free(u1);
00672 goto cleanup;
00673 }
00674 apol_vector_sort(u1->added_cats, level_cat_comp, diff->mod_qpol);
00675 apol_vector_sort(u1->removed_cats, level_cat_comp, diff->orig_qpol);
00676 apol_vector_sort(u1->unmodified_cats, level_cat_comp, diff->orig_qpol);
00677 u1->form = POLDIFF_FORM_MODIFIED;
00678 *orig_pl = u1;
00679 }
00680 retval = 0;
00681 cleanup:
00682 apol_vector_destroy(&added);
00683 apol_vector_destroy(&removed);
00684 apol_vector_destroy(&unmodified);
00685 return retval;
00686 }
|
|
||||||||||||||||||||||||||||
|
Calculate the differences between two sorted vectors of category names. Allocate the vectors added, removed, and unmodified; fill them with appropriate category names. The returned vectors' categories will be sorted alphabetically.
Definition at line 688 of file level_diff.c. References apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, diff, ERR, and poldiff_t. Referenced by level_deep_diff(), level_deep_diff_apol_mls_levels(), and range_deep_diff(). 00690 {
00691 size_t i, j;
00692 char *cat1, *cat2;
00693 int compval, retval = -1, error = 0;
00694 *added = *removed = *unmodified = NULL;
00695 if ((*added = apol_vector_create(free)) == NULL ||
00696 (*removed = apol_vector_create(free)) == NULL || (*unmodified = apol_vector_create(free)) == NULL) {
00697 error = errno;
00698 ERR(diff, "%s", strerror(error));
00699 goto cleanup;
00700 }
00701 for (i = j = 0; i < apol_vector_get_size(v1);) {
00702 if (j >= apol_vector_get_size(v2)) {
00703 break;
00704 }
00705 cat1 = (char *)apol_vector_get_element(v1, i);
00706 cat2 = (char *)apol_vector_get_element(v2, j);
00707 compval = strcmp(cat1, cat2);
00708 if (compval < 0) {
00709 if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*removed, cat1) < 0) {
00710 error = errno;
00711 ERR(diff, "%s", strerror(error));
00712 free(cat1);
00713 goto cleanup;
00714 }
00715 i++;
00716 } else if (compval > 0) {
00717 if ((cat2 = strdup(cat2)) == NULL || apol_vector_append(*added, cat2) < 0) {
00718 error = errno;
00719 ERR(diff, "%s", strerror(error));
00720 free(cat2);
00721 goto cleanup;
00722 }
00723 j++;
00724 } else {
00725 if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*unmodified, cat1) < 0) {
00726 error = errno;
00727 ERR(diff, "%s", strerror(error));
00728 free(cat1);
00729 goto cleanup;
00730 }
00731 i++;
00732 j++;
00733 }
00734 }
00735 for (; i < apol_vector_get_size(v1); i++) {
00736 cat1 = (char *)apol_vector_get_element(v1, i);
00737 if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*removed, cat1) < 0) {
00738 error = errno;
00739 ERR(diff, "%s", strerror(error));
00740 free(cat1);
00741 goto cleanup;
00742 }
00743 }
00744 for (; j < apol_vector_get_size(v2); j++) {
00745 cat2 = (char *)apol_vector_get_element(v2, j);
00746 if ((cat2 = strdup(cat2)) == NULL || apol_vector_append(*added, cat2) < 0) {
00747 error = errno;
00748 ERR(diff, "%s", strerror(error));
00749 free(cat2);
00750 goto cleanup;
00751 }
00752 }
00753 if (apol_vector_get_size(*added) > 0 || apol_vector_get_size(*removed) > 0) {
00754 retval = 1;
00755 } else {
00756 retval = 0;
00757 }
00758 cleanup:
00759 if (retval <= 0) {
00760 /* if no differences found, then destroy all vectors */
00761 apol_vector_destroy(added);
00762 apol_vector_destroy(removed);
00763 apol_vector_destroy(unmodified);
00764 }
00765 if (retval < 0) {
00766 error = errno;
00767 }
00768 return retval;
00769 }
|