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 domain-trans-analysis.h.
#include "policy.h"
#include "vector.h"
#include <qpol/policy.h>
Go to the source code of this file.
Defines | |
| #define | APOL_DOMAIN_TRANS_DIRECTION_FORWARD 0x01 |
| #define | APOL_DOMAIN_TRANS_DIRECTION_REVERSE 0x02 |
| #define | APOL_DOMAIN_TRANS_SEARCH_VALID 0x01 |
| #define | APOL_DOMAIN_TRANS_SEARCH_INVALID 0x02 |
| #define | APOL_DOMAIN_TRANS_SEARCH_BOTH (APOL_DOMAIN_TRANS_SEARCH_VALID|APOL_DOMAIN_TRANS_SEARCH_INVALID) |
| #define | APOL_DOMAIN_TRANS_RULE_PROC_TRANS 0x01 |
| #define | APOL_DOMAIN_TRANS_RULE_EXEC 0x02 |
| #define | APOL_DOMAIN_TRANS_RULE_EXEC_NO_TRANS 0x04 |
| #define | APOL_DOMAIN_TRANS_RULE_ENTRYPOINT 0x08 |
| #define | APOL_DOMAIN_TRANS_RULE_TYPE_TRANS 0x10 |
| #define | APOL_DOMAIN_TRANS_RULE_SETEXEC 0x20 |
Typedefs | |
| typedef apol_domain_trans_analysis | apol_domain_trans_analysis_t |
| typedef apol_domain_trans_result | apol_domain_trans_result_t |
Functions | |
| int | apol_policy_build_domain_trans_table (apol_policy_t *policy) |
| Build the table of domain transitions for a policy if not already built. | |
| int | apol_policy_domain_trans_table_build (apol_policy_t *policy) __attribute__((deprecated)) |
| void | apol_policy_reset_domain_trans_table (apol_policy_t *policy) |
| Reset the state of the domain transition table in a policy. | |
| void | apol_domain_trans_table_reset (apol_policy_t *policy) __attribute__((deprecated)) |
| apol_domain_trans_analysis_t * | apol_domain_trans_analysis_create (void) |
| Allocate and return a new domain transition analysis structure. | |
| void | apol_domain_trans_analysis_destroy (apol_domain_trans_analysis_t **dta) |
| Deallocate all memory associated with the referenced domain transition analysis structure, and then set it to NULL. | |
| int | apol_domain_trans_analysis_set_direction (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, unsigned char direction) |
| Set the direction of the transitions with respect to the start type. | |
| int | apol_domain_trans_analysis_set_valid (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, unsigned char valid) |
| Set the analysis to search for transitions based upon whether they would be permitted. | |
| int | apol_domain_trans_analysis_set_start_type (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *type_name) |
| Set the analysis to begin searching using a given type. | |
| int | apol_domain_trans_analysis_set_result_regex (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *regex) |
| Set the analysis to return only types matching a regular expression. | |
| int | apol_domain_trans_analysis_append_access_type (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *type_name) |
| Set the analysis to return only types having access (via allow rules) to this type. | |
| int | apol_domain_trans_analysis_append_class_perm (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *class_name, const char *perm_name) __attribute__((deprecated)) |
| Set the analysis to return only types having access (via allow rules) to this class with the given permission. | |
| int | apol_domain_trans_analysis_append_class (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *class_name) |
| Set the analysis to return only types having access (via allow rules) to this class. | |
| int | apol_domain_trans_analysis_append_perm (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *perm_name) |
| Set the analysis to return only types having access (via allow rules) to this permission. | |
| int | apol_domain_trans_analysis_do (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t **results) |
| Execute a domain transition analysis against a particular policy. | |
| const qpol_type_t * | apol_domain_trans_result_get_start_type (const apol_domain_trans_result_t *dtr) |
| Return the start type of the transition in an apol_domain_trans_result node. | |
| const qpol_type_t * | apol_domain_trans_result_get_entrypoint_type (const apol_domain_trans_result_t *dtr) |
| Return the entrypoint type of the transition in an apol_domain_trans_result node. | |
| const qpol_type_t * | apol_domain_trans_result_get_end_type (const apol_domain_trans_result_t *dtr) |
| Return the end type of the transition in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_proc_trans_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of process transition rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_entrypoint_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of file entrypoint rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_exec_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of file execute rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_setexec_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of process setexec rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_type_trans_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of type_transition rules (qpol_terule_t pointers) in an apol_domain_trans_result node. | |
| int | apol_domain_trans_result_is_trans_valid (const apol_domain_trans_result_t *dtr) |
| Determine if the transition in an apol_domain_trans_result node is valid. | |
| const apol_vector_t * | apol_domain_trans_result_get_access_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of access rules which satisfied the access types, classes, and permissions specified in the query. | |
| apol_domain_trans_result_t * | apol_domain_trans_result_create_from_domain_trans_result (const apol_domain_trans_result_t *in) |
| Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t object. | |
| void | apol_domain_trans_result_destroy (apol_domain_trans_result_t **res) |
| Free all memory used by an apol_domain_trans_result_t object and set it to NULL. | |
| int | apol_domain_trans_table_verify_trans (apol_policy_t *policy, const qpol_type_t *start_dom, const qpol_type_t *ep_type, const qpol_type_t *end_dom) |
| Verify that a transition using the given three types is valid in the given policy. | |
|
|
Definition at line 41 of file domain-trans-analysis.h. Referenced by apol_domain_trans_analysis_do(), apol_domain_trans_analysis_set_direction(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), and inc_dom_trans_run(). |
|
|
Definition at line 42 of file domain-trans-analysis.h. Referenced by dta_reflexive(), dta_reverse(), dta_reverse_regexp(), and unreachable_doms_run(). |
|
|
Definition at line 44 of file domain-trans-analysis.h. Referenced by unreachable_doms_run(). |
|
|
Definition at line 45 of file domain-trans-analysis.h. Referenced by dta_invalid(), and unreachable_doms_run(). |
|
|
Definition at line 46 of file domain-trans-analysis.h. Referenced by inc_dom_trans_run(). |
|
|
Definition at line 394 of file domain-trans-analysis.h. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and find_avrules_in_node(). |
|
|
Definition at line 395 of file domain-trans-analysis.h. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and find_avrules_in_node(). |
|
|
Definition at line 396 of file domain-trans-analysis.h. |
|
|
Definition at line 397 of file domain-trans-analysis.h. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and find_avrules_in_node(). |
|
|
Definition at line 398 of file domain-trans-analysis.h. Referenced by unreachable_doms_run(). |
|
|
Definition at line 399 of file domain-trans-analysis.h. |
|
|
|
|
Build the table of domain transitions for a policy if not already built.
Definition at line 520 of file domain-trans-analysis.c. References apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_t, apol_domain_trans_table_new(), apol_domain_trans_table_t, apol_policy_t, apol_terule_get_by_query(), apol_terule_query_append_class(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_rules(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_policy::domain_trans_table, domain_trans_table_destroy(), ERR, qpol_avrule_t, QPOL_RULE_ALLOW, QPOL_RULE_TYPE_TRANS, qpol_terule_t, table_add_avrule(), and table_add_terule(). Referenced by apol_domain_trans_analysis_do(), apol_policy_domain_trans_table_build(), apol_types_relation_domain(), dta_init(), and inc_dom_trans_run(). 00521 {
00522 int error = 0;
00523 apol_avrule_query_t *avq = NULL;
00524 apol_terule_query_t *teq = NULL;
00525 apol_vector_t *avrules = NULL;
00526 apol_vector_t *terules = NULL;
00527
00528 if (!policy) {
00529 ERR(policy, "%s", strerror(EINVAL));
00530 errno = EINVAL;
00531 return -1;
00532 }
00533
00534 if (policy->domain_trans_table) {
00535 return 0; /* already built */
00536 }
00537
00538 apol_domain_trans_table_t *dta_table = policy->domain_trans_table = apol_domain_trans_table_new(policy);
00539 if (!policy->domain_trans_table) {
00540 error = errno;
00541 goto err;
00542 }
00543
00544 avq = apol_avrule_query_create();
00545 apol_avrule_query_set_rules(policy, avq, QPOL_RULE_ALLOW);
00546 apol_avrule_query_append_class(policy, avq, "file");
00547 apol_avrule_query_append_class(policy, avq, "process");
00548 apol_avrule_query_append_perm(policy, avq, "execute");
00549 apol_avrule_query_append_perm(policy, avq, "entrypoint");
00550 apol_avrule_query_append_perm(policy, avq, "transition");
00551 apol_avrule_query_append_perm(policy, avq, "setexec");
00552 if (apol_avrule_get_by_query(policy, avq, &avrules)) {
00553 error = errno;
00554 goto err;
00555 }
00556 apol_avrule_query_destroy(&avq);
00557 for (size_t i = 0; i < apol_vector_get_size(avrules); i++) {
00558 if (table_add_avrule(policy, dta_table, (const qpol_avrule_t *)apol_vector_get_element(avrules, i))) {
00559 error = errno;
00560 goto err;
00561 }
00562 }
00563 apol_vector_destroy(&avrules);
00564
00565 teq = apol_terule_query_create();
00566 apol_terule_query_set_rules(policy, teq, QPOL_RULE_TYPE_TRANS);
00567 apol_terule_query_append_class(policy, teq, "process");
00568 if (apol_terule_get_by_query(policy, teq, &terules)) {
00569 error = errno;
00570 goto err;
00571 }
00572 apol_terule_query_destroy(&teq);
00573 for (size_t i = 0; i < apol_vector_get_size(terules); i++) {
00574 if (table_add_terule(policy, dta_table, (const qpol_terule_t *)apol_vector_get_element(terules, i))) {
00575 error = errno;
00576 goto err;
00577 }
00578 }
00579 apol_vector_destroy(&terules);
00580
00581 return 0;
00582
00583 err:
00584 apol_avrule_query_destroy(&avq);
00585 apol_vector_destroy(&avrules);
00586 apol_terule_query_destroy(&teq);
00587 apol_vector_destroy(&terules);
00588 domain_trans_table_destroy(&dta_table);
00589 policy->domain_trans_table = NULL;
00590 errno = error;
00591 return -1;
00592 }
|
|
|
Definition at line 594 of file domain-trans-analysis.c. References apol_policy_build_domain_trans_table(), and apol_policy_t. 00595 {
00596 return apol_policy_build_domain_trans_table(policy);
00597 }
|
|
|
Reset the state of the domain transition table in a policy. This is needed because by default subsequent calls to apol_domain_trans_analysis_do() will not produce results generated in a previous call. If calls are to be considered independent or calls in a different direction are desired, call this function prior to apol_domain_trans_analysis_do(). If the table was not built yet then this function does nothing.
Definition at line 610 of file domain-trans-analysis.c. References apol_bst_inorder_map(), apol_policy_t, dom_node_reset(), apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, and ep_node_reset(). Referenced by apol_domain_trans_table_reset(), apol_domain_trans_table_verify_trans(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), and unreachable_doms_run(). 00611 {
00612 if (!policy || !policy->domain_trans_table)
00613 return;
00614 apol_bst_inorder_map(policy->domain_trans_table->domain_table, dom_node_reset, NULL);
00615 apol_bst_inorder_map(policy->domain_trans_table->entrypoint_table, ep_node_reset, NULL);
00616 return;
00617 }
|
|
|
Definition at line 619 of file domain-trans-analysis.c. References apol_policy_reset_domain_trans_table(), and apol_policy_t. 00620 {
00621 apol_policy_reset_domain_trans_table(policy);
00622 }
|
|
|
Allocate and return a new domain transition analysis structure. All fields are cleared; one must fill in the details of the analysis before running it. The caller must call apol_domain_trans_analysis_destroy() upon the return value afterwards.
Definition at line 625 of file domain-trans-analysis.c. References apol_domain_trans_analysis_destroy(), apol_domain_trans_analysis_t, and apol_domain_trans_analysis::valid. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00626 {
00627 apol_domain_trans_analysis_t *new_dta = NULL;
00628 int error = 0;
00629
00630 if (!(new_dta = calloc(1, sizeof(apol_domain_trans_analysis_t)))) {
00631 error = errno;
00632 goto err;
00633 }
00634
00635 new_dta->valid = APOL_DOMAIN_TRANS_SEARCH_VALID; /* by default search only valid transitions */
00636
00637 return new_dta;
00638
00639 err:
00640 apol_domain_trans_analysis_destroy(&new_dta);
00641 errno = error;
00642 return NULL;
00643 }
|
|
|
Deallocate all memory associated with the referenced domain transition analysis structure, and then set it to NULL. This function does nothing if the analysis is already NULL.
Definition at line 645 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_regex_destroy(), and apol_vector_destroy(). Referenced by apol_domain_trans_analysis_create(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00646 {
00647 if (!dta || !(*dta))
00648 return;
00649
00650 free((*dta)->start_type);
00651 free((*dta)->result);
00652 apol_vector_destroy(&((*dta)->access_types));
00653 apol_vector_destroy(&((*dta)->access_classes));
00654 apol_vector_destroy(&((*dta)->access_perms));
00655 apol_regex_destroy(&((*dta)->result_regex));
00656 free(*dta);
00657 *dta = NULL;
00658 }
|
|
||||||||||||||||
|
Set the direction of the transitions with respect to the start type. Must be either APOL_DOMAIN_TRANS_DIRECTION_FORWARD or APOL_DOMAIN_TRANS_DIRECTION_REVERSE.
Definition at line 660 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_policy_t, apol_domain_trans_analysis::direction, and ERR. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00662 {
00663 if (!dta || (direction != APOL_DOMAIN_TRANS_DIRECTION_FORWARD && direction != APOL_DOMAIN_TRANS_DIRECTION_REVERSE)) {
00664 ERR(policy, "Error setting analysis direction: %s", strerror(EINVAL));
00665 errno = EINVAL;
00666 return -1;
00667 }
00668
00669 dta->direction = direction;
00670
00671 return 0;
00672 }
|
|
||||||||||||||||
|
Set the analysis to search for transitions based upon whether they would be permitted. The value must be one of APOL_DOMAIN_TRANS_SEARCH_* defined above. The default for a newly created analysis is to search for only valid transitions (i.e. APOL_DOMAIN_TRANS_SEARCH_VALID).
Definition at line 674 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::valid. Referenced by dta_invalid(), inc_dom_trans_run(), and unreachable_doms_run(). 00675 {
00676 if (!dta || valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH)) {
00677 ERR(policy, "Error setting analysis validity flag: %s", strerror(EINVAL));
00678 errno = EINVAL;
00679 return -1;
00680 }
00681
00682 dta->valid = valid;
00683
00684 return 0;
00685 }
|
|
||||||||||||||||
|
Set the analysis to begin searching using a given type. This function must be called prior to running the analysis. If a previous type was set, it will be free()'d first.
Definition at line 687 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::start_type. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00689 {
00690 char *tmp = NULL;
00691 int error = 0;
00692
00693 if (!dta || !type_name) {
00694 ERR(policy, "%s", strerror(EINVAL));
00695 errno = EINVAL;
00696 return -1;
00697 }
00698
00699 if (!(tmp = strdup(type_name))) {
00700 error = errno;
00701 ERR(policy, "%s", strerror(error));
00702 errno = error;
00703 return -1;
00704 }
00705
00706 free(dta->start_type);
00707 dta->start_type = tmp;
00708
00709 return 0;
00710 }
|
|
||||||||||||||||
|
Set the analysis to return only types matching a regular expression. Note that the regular expression will also match types' aliases.
Definition at line 712 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, apol_query_set(), apol_regex_destroy(), ERR, apol_domain_trans_analysis::result, and apol_domain_trans_analysis::result_regex. Referenced by dta_reverse_regexp(). 00713 {
00714 if (!dta) {
00715 ERR(policy, "%s", strerror(EINVAL));
00716 errno = EINVAL;
00717 return -1;
00718 }
00719
00720 if (!regex) {
00721 apol_regex_destroy(&dta->result_regex);
00722 return 0;
00723 }
00724
00725 return apol_query_set(policy, &dta->result, &dta->result_regex, regex);
00726 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this type. This is only valid for forward analysis. If more than one type is appended to the query, the resulting type must have access to at least one of the appended types. Pass a NULL to clear all previously appended types. If access types are appended, the caller must also call apol_domain_trans_analysis_append_class() at least once with a valid class and apol_domain_trans_analysis_append_perm() at least once with a valid permission.
Definition at line 728 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_types, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by dta_forward_access(). 00730 {
00731 char *tmp = NULL;
00732 int error = 0;
00733
00734 if (!dta) {
00735 ERR(policy, "Error appending type to analysis: %s", strerror(EINVAL));
00736 errno = EINVAL;
00737 return -1;
00738 }
00739
00740 if (!type_name) {
00741 apol_vector_destroy(&dta->access_types);
00742 return 0;
00743 }
00744
00745 if (!dta->access_types) {
00746 if (!(dta->access_types = apol_vector_create(free))) {
00747 error = errno;
00748 ERR(policy, "%s", strerror(error));
00749 errno = error;
00750 return -1;
00751 }
00752 }
00753
00754 if (!(tmp = strdup(type_name))) {
00755 error = errno;
00756 ERR(policy, "%s", strerror(error));
00757 errno = error;
00758 return -1;
00759 }
00760
00761 if (apol_vector_append(dta->access_types, tmp)) {
00762 error = errno;
00763 free(tmp);
00764 ERR(policy, "%s", strerror(error));
00765 errno = error;
00766 return -1;
00767 }
00768
00769 return 0;
00770 }
|
|
||||||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this class with the given permission. This is only valid for forward analysis. If more than one class is appended to the query, the resulting type must have access to at least one of the appended classes. If more than one permission is appended for the same class, the resulting type must have at least one of the appended permissions for that class. Pass a NULL to both strings to clear all previously appended classes and permissions. If access classes and permissions are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type.
Definition at line 772 of file domain-trans-analysis.c. References apol_domain_trans_analysis_append_class(), apol_domain_trans_analysis_append_perm(), apol_domain_trans_analysis_t, and apol_policy_t. 00774 {
00775 if (apol_domain_trans_analysis_append_class(policy, dta, class_name))
00776 return -1;
00777 return apol_domain_trans_analysis_append_perm(policy, dta, perm_name);
00778 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this class. This is only valid for forward analysis. If more than one class is appended to the query, the resulting type must have access to at least one of the appended classes. Pass a NULL to clear all previously appended classes. If access classes are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type and apol_domain_trans_analysis_append_perm() with a valid permission.
Definition at line 780 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access(). 00782 {
00783 char *tmp = NULL;
00784 int error = 0;
00785
00786 if (!dta) {
00787 ERR(policy, "Error appending class to analysis: %s", strerror(EINVAL));
00788 errno = EINVAL;
00789 return -1;
00790 }
00791
00792 if (!class_name) {
00793 apol_vector_destroy(&dta->access_classes);
00794 return 0;
00795 }
00796
00797 if (!dta->access_classes) {
00798 if (!(dta->access_classes = apol_vector_create(free))) {
00799 error = errno;
00800 ERR(policy, "%s", strerror(error));
00801 errno = error;
00802 return -1;
00803 }
00804 }
00805
00806 if (!(tmp = strdup(class_name))) {
00807 error = errno;
00808 ERR(policy, "%s", strerror(error));
00809 errno = error;
00810 return -1;
00811 }
00812
00813 if (apol_vector_append(dta->access_classes, tmp)) {
00814 error = errno;
00815 free(tmp);
00816 ERR(policy, "%s", strerror(error));
00817 errno = error;
00818 return -1;
00819 }
00820
00821 return 0;
00822 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this permission. This is only valid for forward analysis. If more than one permission is appended the resulting type must have at least one of the appended permissions. Pass a NULL to clear all previously appended permissions. If access permissions are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type and apol_domain_trans_analysis_append_class() at least once with a valid class.
Definition at line 824 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_perms, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access(). 00825 {
00826 char *tmp = NULL;
00827 int error = 0;
00828
00829 if (!dta) {
00830 ERR(policy, "Error appending perm to analysis: %s", strerror(EINVAL));
00831 errno = EINVAL;
00832 return -1;
00833 }
00834
00835 if (!perm_name) {
00836 apol_vector_destroy(&dta->access_perms);
00837 return 0;
00838 }
00839
00840 if (!dta->access_perms) {
00841 if (!(dta->access_perms = apol_vector_create(free))) {
00842 error = errno;
00843 ERR(policy, "%s", strerror(error));
00844 errno = error;
00845 return -1;
00846 }
00847 }
00848
00849 if (!(tmp = strdup(perm_name))) {
00850 error = errno;
00851 ERR(policy, "%s", strerror(error));
00852 errno = error;
00853 return -1;
00854 }
00855
00856 if (apol_vector_append(dta->access_perms, tmp)) {
00857 error = errno;
00858 free(tmp);
00859 ERR(policy, "%s", strerror(error));
00860 errno = error;
00861 return -1;
00862 }
00863
00864 return 0;
00865 }
|
|
||||||||||||||||
|
Execute a domain transition analysis against a particular policy.
Definition at line 1627 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis::access_perms, apol_domain_trans_result::access_rules, apol_domain_trans_analysis::access_types, apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_set_source(), apol_avrule_query_set_target(), apol_avrule_query_t, apol_compare_type(), apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_t, apol_policy_build_domain_trans_table(), apol_policy_get_qpol(), apol_policy_t, APOL_QUERY_REGEX, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_remove(), apol_vector_t, apol_domain_trans_analysis::direction, domain_trans_result_free(), apol_policy::domain_trans_table, domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), apol_domain_trans_result::end_type, ERR, apol_policy::p, qpol_policy_get_type_by_name(), QPOL_RULE_ALLOW, qpol_type_get_isattr(), qpol_type_get_name(), qpol_type_t, apol_domain_trans_analysis::result, apol_domain_trans_analysis::result_regex, apol_domain_trans_analysis::start_type, apol_domain_trans_result::start_type, apol_domain_trans_analysis::valid, and apol_domain_trans_result::valid. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 01628 {
01629 apol_vector_t *local_results = NULL;
01630 apol_avrule_query_t *accessq = NULL;
01631 int error = 0;
01632 if (!results)
01633 *results = NULL;
01634 if (!policy || !dta || !results) {
01635 ERR(policy, "%s", strerror(EINVAL));
01636 errno = EINVAL;
01637 return -1;
01638 }
01639
01640 /* build table if not already present */
01641 if (!(policy->domain_trans_table)) {
01642 if (apol_policy_build_domain_trans_table(policy))
01643 return -1; /* errors already reported by build function */
01644 }
01645
01646 /* validate analysis options */
01647 if (dta->direction == 0 || dta->valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH) || !(dta->start_type)) {
01648 error = EINVAL;
01649 ERR(policy, "%s", strerror(EINVAL));
01650 goto err;
01651 }
01652 size_t num_atypes = apol_vector_get_size(dta->access_types);
01653 size_t num_aclasses = apol_vector_get_size(dta->access_classes);
01654 size_t num_aprems = apol_vector_get_size(dta->access_perms);
01655 if ((num_atypes == 0 && (num_aclasses != 0 || num_aprems != 0)) ||
01656 (num_aclasses == 0 && (num_atypes != 0 || num_aprems != 0)) ||
01657 (num_aprems == 0 && (num_aclasses != 0 || num_atypes != 0))) {
01658 error = EINVAL;
01659 ERR(policy, "%s", strerror(EINVAL));
01660 goto err;
01661 }
01662
01663 /* get starting type */
01664 const qpol_type_t *start_type = NULL;
01665 if (qpol_policy_get_type_by_name(policy->p, dta->start_type, &start_type)) {
01666 error = errno;
01667 ERR(policy, "Unable to perform analysis: Invalid starting type %s", dta->start_type);
01668 goto err;
01669 }
01670 unsigned char isattr = 0;
01671 qpol_type_get_isattr(policy->p, start_type, &isattr);
01672 if (isattr) {
01673 ERR(policy, "%s", "Attributes are not valid here.");
01674 error = EINVAL;
01675 goto err;
01676 }
01677
01678 local_results = apol_vector_create(domain_trans_result_free);
01679 /* get all transitions for the requested direction */
01680 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01681 if (domain_trans_table_get_all_reverse_trans(policy, dta, local_results, start_type)) {
01682 error = errno;
01683 goto err;
01684 }
01685 } else {
01686 if (domain_trans_table_get_all_forward_trans(policy, dta, local_results, start_type)) {
01687 error = errno;
01688 goto err;
01689 }
01690 }
01691
01692 /* if requested, filter by validity */
01693 if (dta->valid != APOL_DOMAIN_TRANS_SEARCH_BOTH) {
01694 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01695 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01696 if (res->valid != (dta->valid == APOL_DOMAIN_TRANS_SEARCH_VALID)) {
01697 apol_vector_remove(local_results, i);
01698 domain_trans_result_free(res);
01699 } else {
01700 i++;
01701 }
01702 }
01703 }
01704
01705 /* if filtering by result type, do that now */
01706 if (dta->result) {
01707 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01708 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01709 const qpol_type_t *type = NULL;
01710 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01711 type = res->start_type;
01712 } else {
01713 type = res->end_type;
01714 }
01715 int compval = apol_compare_type(policy, type, dta->result, APOL_QUERY_REGEX, &dta->result_regex);
01716 if (compval < 0) {
01717 error = errno;
01718 goto err;
01719 } else if (compval > 0) {
01720 i++;
01721 } else {
01722 apol_vector_remove(local_results, i);
01723 domain_trans_result_free(res);
01724 }
01725 }
01726 }
01727
01728 /* finally do access filtering */
01729 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_FORWARD && num_atypes && num_aclasses && num_aprems) {
01730 accessq = apol_avrule_query_create();
01731 apol_avrule_query_set_rules(policy, accessq, QPOL_RULE_ALLOW);
01732 for (size_t i = 0; i < num_aclasses; i++) {
01733 if (apol_avrule_query_append_class
01734 (policy, accessq, (char *)apol_vector_get_element(dta->access_classes, i))) {
01735 error = errno;
01736 goto err;
01737 }
01738 }
01739 for (size_t i = 0; i < num_aprems; i++) {
01740 if (apol_avrule_query_append_perm(policy, accessq, (char *)apol_vector_get_element(dta->access_perms, i))) {
01741 error = errno;
01742 goto err;
01743 }
01744 }
01745 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01746 const char *end_name = NULL;
01747 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01748 if (qpol_type_get_name(apol_policy_get_qpol(policy), res->end_type, &end_name) ||
01749 apol_avrule_query_set_source(policy, accessq, end_name, 1)) {
01750 error = errno;
01751 goto err;
01752 }
01753 apol_vector_t *tmp_access = apol_vector_create(NULL);
01754 for (size_t j = 0; j < num_atypes; j++) {
01755 if (apol_avrule_query_set_target
01756 (policy, accessq, (char *)apol_vector_get_element(dta->access_types, j), 1)) {
01757 error = errno;
01758 apol_vector_destroy(&tmp_access);
01759 goto err;
01760 }
01761 apol_vector_t *cur_tgt_v = NULL;
01762 apol_avrule_get_by_query(policy, accessq, &cur_tgt_v);
01763 apol_vector_cat(tmp_access, cur_tgt_v);
01764 apol_vector_destroy(&cur_tgt_v);
01765 }
01766 if (apol_vector_get_size(tmp_access)) {
01767 res->access_rules = tmp_access;
01768 tmp_access = NULL;
01769 i++;
01770 } else {
01771 apol_vector_remove(local_results, i);
01772 domain_trans_result_free(res);
01773 }
01774 apol_vector_destroy(&tmp_access);
01775 }
01776 apol_avrule_query_destroy(&accessq);
01777 }
01778
01779 *results = apol_vector_create(domain_trans_result_free);
01780 if (!(*results)) {
01781 error = errno;
01782 goto err;
01783 }
01784 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01785 apol_domain_trans_result_t *res =
01786 apol_domain_trans_result_create_from_domain_trans_result((apol_domain_trans_result_t *)
01787 apol_vector_get_element(local_results, i));
01788 if (!res || apol_vector_append(*results, (void *)res)) {
01789 error = errno;
01790 domain_trans_result_free(res);
01791 goto err;
01792 }
01793 }
01794 apol_vector_destroy(&local_results);
01795
01796 return 0;
01797 err:
01798 apol_vector_destroy(&local_results);
01799 apol_vector_destroy(results);
01800 apol_avrule_query_destroy(&accessq);
01801 errno = error;
01802 return -1;
01803 }
|
|
|
Return the start type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no start type in which case NULL is returned.
Definition at line 1807 of file domain-trans-analysis.c. References apol_domain_trans_result_t, qpol_type_t, and apol_domain_trans_result::start_type. Referenced by dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run(). 01808 {
01809 if (dtr) {
01810 return dtr->start_type;
01811 } else {
01812 errno = EINVAL;
01813 return NULL;
01814 }
01815 }
|
|
|
Return the entrypoint type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no entrypoint in which case NULL is returned.
Definition at line 1817 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_domain_trans_result::ep_type, and qpol_type_t. Referenced by dta_forward(), dta_forward_multi_end(), dta_invalid(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run(). 01818 {
01819 if (dtr) {
01820 return dtr->ep_type;
01821 } else {
01822 errno = EINVAL;
01823 return NULL;
01824 }
01825 }
|
|
|
Return the end type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no end type in which case NULL is returned.
Definition at line 1827 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_domain_trans_result::end_type, and qpol_type_t. Referenced by apol_types_relation_clone_domaintrans(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), and inc_dom_trans_run(). 01828 {
01829 if (dtr) {
01830 return dtr->end_type;
01831 } else {
01832 errno = EINVAL;
01833 return NULL;
01834 }
01835 }
|
|
|
Return the vector of process transition rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1837 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::proc_trans_rules. Referenced by dta_invalid(). 01838 {
01839 if (dtr) {
01840 return dtr->proc_trans_rules;
01841 } else {
01842 errno = EINVAL;
01843 return NULL;
01844 }
01845 }
|
|
|
Return the vector of file entrypoint rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1847 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::ep_rules. Referenced by dta_invalid(). 01848 {
01849 if (dtr) {
01850 return dtr->ep_rules;
01851 } else {
01852 errno = EINVAL;
01853 return NULL;
01854 }
01855 }
|
|
|
Return the vector of file execute rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1857 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::exec_rules. Referenced by dta_invalid(). 01858 {
01859 if (dtr) {
01860 return dtr->exec_rules;
01861 } else {
01862 errno = EINVAL;
01863 return NULL;
01864 }
01865 }
|
|
|
Return the vector of process setexec rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. For all policies of version 15 or later a transition requires either a setexec rule or a type_transition rule to be valid. Valid transitions may have both; if there is no rule, this function returns an empty vector.
Definition at line 1867 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::setexec_rules. Referenced by dta_invalid(). 01868 {
01869 if (dtr) {
01870 return dtr->setexec_rules;
01871 } else {
01872 errno = EINVAL;
01873 return NULL;
01874 }
01875 }
|
|
|
Return the vector of type_transition rules (qpol_terule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. For all policies of version 15 or later a transition requires either a setexec rule or a type_transition rule to be valid. Valid transitions may have both; if there is no rule, this function returns an empty vector.
Definition at line 1877 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::type_trans_rules. Referenced by dta_invalid(). 01878 {
01879 if (dtr) {
01880 return dtr->type_trans_rules;
01881 } else {
01882 errno = EINVAL;
01883 return NULL;
01884 }
01885 }
|
|
|
Determine if the transition in an apol_domain_trans_result node is valid.
Definition at line 1887 of file domain-trans-analysis.c. References apol_domain_trans_result_t, and apol_domain_trans_result::valid. Referenced by dta_invalid(). 01888 {
01889 if (dtr) {
01890 return dtr->valid;
01891 } else {
01892 errno = EINVAL;
01893 return 0;
01894 }
01895 }
|
|
|
Return the vector of access rules which satisfied the access types, classes, and permissions specified in the query. This is a vector of qpol_avrule_t pointers. The caller should not call apol_vector_destroy() upon the returned vector. This vector is only populated if access criteria were specified in the analysis.
Definition at line 1897 of file domain-trans-analysis.c. References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, and apol_vector_t. Referenced by dta_forward_access(). 01898 {
01899 if (dtr) {
01900 return dtr->access_rules;
01901 } else {
01902 errno = EINVAL;
01903 return NULL;
01904 }
01905 }
|
|
|
Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t object. The caller is responsible for calling apol_domain_trans_result_destroy() upon the returned value.
Definition at line 2008 of file domain-trans-analysis.c. References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, apol_vector_create_from_vector(), domain_trans_result_free(), apol_domain_trans_result::end_type, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, apol_domain_trans_result::proc_trans_rules, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, apol_domain_trans_result::type_trans_rules, and apol_domain_trans_result::valid. Referenced by apol_domain_trans_analysis_do(), apol_types_relation_clone_domaintrans(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and inc_dom_trans_run(). 02009 {
02010 apol_domain_trans_result_t *new_r = NULL;
02011 int retval = -1;
02012 if ((new_r = calloc(1, sizeof(*new_r))) == NULL) {
02013 goto cleanup;
02014 }
02015 if (result->proc_trans_rules != NULL &&
02016 (new_r->proc_trans_rules = apol_vector_create_from_vector(result->proc_trans_rules, NULL, NULL, NULL)) == NULL) {
02017 goto cleanup;
02018 }
02019 if (result->ep_rules != NULL
02020 && (new_r->ep_rules = apol_vector_create_from_vector(result->ep_rules, NULL, NULL, NULL)) == NULL) {
02021 goto cleanup;
02022 }
02023 if (result->exec_rules != NULL
02024 && (new_r->exec_rules = apol_vector_create_from_vector(result->exec_rules, NULL, NULL, NULL)) == NULL) {
02025 goto cleanup;
02026 }
02027 if (result->setexec_rules != NULL
02028 && (new_r->setexec_rules = apol_vector_create_from_vector(result->setexec_rules, NULL, NULL, NULL)) == NULL) {
02029 goto cleanup;
02030 }
02031 if (result->type_trans_rules != NULL &&
02032 (new_r->type_trans_rules = apol_vector_create_from_vector(result->type_trans_rules, NULL, NULL, NULL)) == NULL) {
02033 goto cleanup;
02034 }
02035 if (result->access_rules != NULL
02036 && (new_r->access_rules = apol_vector_create_from_vector(result->access_rules, NULL, NULL, NULL)) == NULL) {
02037 goto cleanup;
02038 }
02039 new_r->start_type = result->start_type;
02040 new_r->ep_type = result->ep_type;
02041 new_r->end_type = result->end_type;
02042 new_r->valid = result->valid;
02043 retval = 0;
02044 cleanup:
02045 if (retval != 0) {
02046 domain_trans_result_free(new_r);
02047 return NULL;
02048 }
02049 return new_r;
02050 }
|
|
|
Free all memory used by an apol_domain_trans_result_t object and set it to NULL. This does nothing if the pointer is already NULL. This should only be called for results created by apol_domain_trans_result_create_from_domain_trans_result() and not those returned from within vectors.
Definition at line 2070 of file domain-trans-analysis.c. References apol_domain_trans_result_t, and domain_trans_result_free(). Referenced by domain_trans_result_create(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and dtr_free_wrap(). 02071 {
02072 if (!res || !(*res))
02073 return;
02074 domain_trans_result_free((void *)*res);
02075 *res = NULL;
02076 }
|
|
||||||||||||||||||||
|
Verify that a transition using the given three types is valid in the given policy. If not valid, return a value indicating the missing rules. If any type is NULL, rules that would contain that type are considered missing. A valid transition requires a process transition, an entrypoint, and an execute rule. If the policy is version 15 or later it also requires either a setexec rule or a type_transition rule. The value APOL_DOMAIN_TRANS_RULE_EXEC_NO_TRANS is not returned by this function.
Definition at line 1907 of file domain-trans-analysis.c. References apol_bst_get_element(), APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_get_qpol(), apol_policy_reset_domain_trans_table(), apol_policy_t, apol_terule_get_by_query(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_default(), apol_terule_query_set_rules(), apol_terule_query_set_source(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, dom_node_t, apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, ep_node_t, find_avrules_in_node(), find_terules_in_node(), QPOL_RULE_TYPE_TRANS, qpol_type_get_name(), and requires_setexec_or_type_trans(). Referenced by inc_dom_trans_run(), and unreachable_doms_run(). 01909 {
01910 int missing_rules = 0;
01911
01912 if (!policy || !policy->domain_trans_table) {
01913 errno = EINVAL;
01914 return -1;
01915 }
01916 //reset the table
01917 apol_policy_reset_domain_trans_table(policy);
01918 //find nodes for each type
01919 dom_node_t start_dummy = { start_dom, NULL, NULL, NULL };
01920 dom_node_t *start_node = NULL;
01921 if (start_dom)
01922 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&start_dummy, NULL, (void **)&start_node);
01923 ep_node_t ep_dummy = { ep_type, NULL, NULL };
01924 ep_node_t *ep_node = NULL;
01925 if (ep_type)
01926 apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&ep_dummy, NULL, (void **)&ep_node);
01927 dom_node_t end_dummy = { end_dom, NULL, NULL, NULL };
01928 dom_node_t *end_node = NULL;
01929 if (end_dom)
01930 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&end_dummy, NULL, (void **)&end_node);
01931
01932 bool tt = false, sx = false, ex = false, pt = false, ep = false;
01933
01934 //find process transition rule
01935 if (start_node && end_dom) {
01936 apol_vector_t *v = find_avrules_in_node(start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, end_dom);
01937 if (apol_vector_get_size(v))
01938 pt = true;
01939 apol_vector_destroy(&v);
01940 }
01941 //find execute rule
01942 if (start_dom && ep_node) {
01943 apol_vector_t *v = find_avrules_in_node(ep_node, APOL_DOMAIN_TRANS_RULE_EXEC, start_dom);
01944 if (apol_vector_get_size(v))
01945 ex = true;
01946 apol_vector_destroy(&v);
01947 }
01948 //find entrypoint rules
01949 if (end_node && ep_type) {
01950 apol_vector_t *v = find_avrules_in_node(end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, ep_type);
01951 if (apol_vector_get_size(v))
01952 ep = true;
01953 apol_vector_destroy(&v);
01954 }
01955 if (requires_setexec_or_type_trans(policy)) {
01956 //find setexec rule
01957 if (start_node)
01958 if (apol_vector_get_size(start_node->setexec_rules))
01959 sx = true;
01960 //find type_transition rule
01961 if (ep_node && start_dom && end_dom) {
01962 apol_vector_t *v = find_terules_in_node(ep_node, start_dom, end_dom);
01963 if (apol_vector_get_size(v)) {
01964 tt = true;
01965 }
01966 apol_vector_destroy(&v);
01967 }
01968 } else {
01969 //old policy version - pretend these exist
01970 tt = sx = true;
01971 }
01972
01973 if (!(pt && ep && ex && (tt || sx))) {
01974 if (!pt)
01975 missing_rules |= APOL_DOMAIN_TRANS_RULE_PROC_TRANS;
01976 if (!ep)
01977 missing_rules |= APOL_DOMAIN_TRANS_RULE_ENTRYPOINT;
01978 if (!ex)
01979 missing_rules |= APOL_DOMAIN_TRANS_RULE_EXEC;
01980 if (!tt && !sx) {
01981 missing_rules |= APOL_DOMAIN_TRANS_RULE_SETEXEC;
01982 //do not report type_transition as missing if there is one for another entrypoint as this would be invalid
01983 const char *start_name = NULL, *end_name = NULL;
01984 qpol_type_get_name(apol_policy_get_qpol(policy), start_dom, &start_name);
01985 qpol_type_get_name(apol_policy_get_qpol(policy), end_dom, &end_name);
01986 apol_terule_query_t *tq = NULL;
01987 if (!start_name || !end_name || !(tq = apol_terule_query_create())) {
01988 return -1;
01989 }
01990 apol_terule_query_set_rules(policy, tq, QPOL_RULE_TYPE_TRANS);
01991 apol_terule_query_set_source(policy, tq, start_name, 1);
01992 apol_terule_query_set_default(policy, tq, end_name);
01993 apol_vector_t *v = NULL;
01994 if (apol_terule_get_by_query(policy, tq, &v)) {
01995 apol_terule_query_destroy(&tq);
01996 return -1;
01997 }
01998 apol_terule_query_destroy(&tq);
01999 if (!apol_vector_get_size(v))
02000 missing_rules |= APOL_DOMAIN_TRANS_RULE_TYPE_TRANS;
02001 apol_vector_destroy(&v);
02002 }
02003 }
02004
02005 return missing_rules;
02006 }
|