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_internal.h.
Go to the source code of this file.
Classes | |
| struct | poldiff_level |
Typedefs | |
| typedef poldiff_level_summary | poldiff_level_summary_t |
Functions | |
| 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. | |
| 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. | |
| 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_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. | |
|
|
Definition at line 35 of file level_internal.h. Referenced by level_create(), and level_destroy(). |
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|