diff options
Diffstat (limited to 'libqpol/src/avrule_query.c')
-rw-r--r-- | libqpol/src/avrule_query.c | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/libqpol/src/avrule_query.c b/libqpol/src/avrule_query.c new file mode 100644 index 0000000..749565b --- /dev/null +++ b/libqpol/src/avrule_query.c @@ -0,0 +1,288 @@ + /** + * @file + * Implementation for the public interface for searching and iterating over avrules. + * + * @author Kevin Carr kcarr@tresys.com + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2006-2007 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "iterator_internal.h" +#include <qpol/iterator.h> +#include <qpol/policy.h> +#include <qpol/avrule_query.h> +#include <sepol/policydb/policydb.h> +#include <sepol/policydb/avtab.h> +#include <sepol/policydb/util.h> +#include <stdlib.h> +#include "qpol_internal.h" + +int qpol_policy_get_avrule_iter(const qpol_policy_t * policy, uint32_t rule_type_mask, qpol_iterator_t ** iter) +{ + policydb_t *db; + avtab_state_t *state; + + if (iter) { + *iter = NULL; + } + if (policy == NULL || iter == NULL) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + +#if 1 // Seems to make sediff/sediffx work better without breaking things + if (!qpol_policy_has_capability(policy, QPOL_CAP_RULES_LOADED)) { + ERR(policy, "%s", "Cannot get avrules: Rules not loaded"); + errno = ENOTSUP; + return STATUS_ERR; + } +#endif + + if ((rule_type_mask & QPOL_RULE_NEVERALLOW) && !qpol_policy_has_capability(policy, QPOL_CAP_NEVERALLOW)) { + ERR(policy, "%s", "Cannot get avrules: Neverallow rules requested but not available"); + errno = ENOTSUP; + return STATUS_ERR; + } + + db = &policy->p->p; + + state = calloc(1, sizeof(avtab_state_t)); + if (state == NULL) { + ERR(policy, "%s", strerror(ENOMEM)); + errno = ENOMEM; + return STATUS_ERR; + } + state->ucond_tab = &db->te_avtab; + state->cond_tab = &db->te_cond_avtab; + state->rule_type_mask = rule_type_mask; + state->node = db->te_avtab.htable[0]; + + if (qpol_iterator_create + (policy, state, avtab_state_get_cur, avtab_state_next, avtab_state_end, avtab_state_size, free, iter)) { + free(state); + return STATUS_ERR; + } + if (state->node == NULL || !(state->node->key.specified & state->rule_type_mask)) { + avtab_state_next(*iter); + } + return STATUS_SUCCESS; +} + +int qpol_avrule_get_source_type(const qpol_policy_t * policy, const qpol_avrule_t * rule, const qpol_type_t ** source) +{ + policydb_t *db = NULL; + avtab_ptr_t avrule = NULL; + + if (source) { + *source = NULL; + } + + if (!policy || !rule || !source) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + db = &policy->p->p; + avrule = (avtab_ptr_t) rule; + + *source = (qpol_type_t *) db->type_val_to_struct[avrule->key.source_type - 1]; + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_target_type(const qpol_policy_t * policy, const qpol_avrule_t * rule, const qpol_type_t ** target) +{ + policydb_t *db = NULL; + avtab_ptr_t avrule = NULL; + + if (target) { + *target = NULL; + } + + if (!policy || !rule || !target) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + db = &policy->p->p; + avrule = (avtab_ptr_t) rule; + + *target = (qpol_type_t *) db->type_val_to_struct[avrule->key.target_type - 1]; + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_object_class(const qpol_policy_t * policy, const qpol_avrule_t * rule, const qpol_class_t ** obj_class) +{ + policydb_t *db = NULL; + avtab_ptr_t avrule = NULL; + + if (obj_class) { + *obj_class = NULL; + } + + if (!policy || !rule || !obj_class) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + db = &policy->p->p; + avrule = (avtab_ptr_t) rule; + + *obj_class = (qpol_class_t *) db->class_val_to_struct[avrule->key.target_class - 1]; + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_perm_iter(const qpol_policy_t * policy, const qpol_avrule_t * rule, qpol_iterator_t ** perms) +{ + policydb_t *db = NULL; + avtab_ptr_t avrule = NULL; + perm_state_t *ps = NULL; + + if (perms) { + *perms = NULL; + } + + if (!policy || !rule || !perms) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + db = &policy->p->p; + avrule = (avtab_ptr_t) rule; + ps = calloc(1, sizeof(perm_state_t)); + if (!ps) { + return STATUS_ERR; + } + if (avrule->key.specified & QPOL_RULE_DONTAUDIT) { + ps->perm_set = ~(avrule->datum.data); /* stored as auditdeny flip the bits */ + } else { + ps->perm_set = avrule->datum.data; + } + ps->obj_class_val = avrule->key.target_class; + + if (qpol_iterator_create(policy, (void *)ps, perm_state_get_cur, + perm_state_next, perm_state_end, perm_state_size, free, perms)) { + return STATUS_ERR; + } + + if (!(ps->perm_set & 1)) /* defaults to bit 0, if off: advance */ + perm_state_next(*perms); + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_rule_type(const qpol_policy_t * policy, const qpol_avrule_t * rule, uint32_t * rule_type) +{ + policydb_t *db = NULL; + avtab_ptr_t avrule = NULL; + + if (rule_type) { + *rule_type = 0; + } + + if (!policy || !rule || !rule_type) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + db = &policy->p->p; + avrule = (avtab_ptr_t) rule; + + *rule_type = + (avrule->key.specified & (QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT)); + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_cond(const qpol_policy_t * policy, const qpol_avrule_t * rule, const qpol_cond_t ** cond) +{ + avtab_ptr_t avrule = NULL; + + if (cond) { + *cond = NULL; + } + + if (!policy || !rule || !cond) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + avrule = (avtab_ptr_t) rule; + + *cond = (qpol_cond_t *) avrule->parse_context; + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_is_enabled(const qpol_policy_t * policy, const qpol_avrule_t * rule, uint32_t * is_enabled) +{ + avtab_ptr_t avrule = NULL; + + if (is_enabled) { + *is_enabled = 0; + } + + if (!policy || !rule || !is_enabled) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + avrule = (avtab_ptr_t) rule; + + *is_enabled = ((avrule->merged & QPOL_COND_RULE_ENABLED) ? 1 : 0); + + return STATUS_SUCCESS; +} + +int qpol_avrule_get_which_list(const qpol_policy_t * policy, const qpol_avrule_t * rule, uint32_t * which_list) +{ + avtab_ptr_t avrule = NULL; + + if (which_list) { + *which_list = 0; + } + + if (!policy || !rule || !which_list) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + avrule = (avtab_ptr_t) rule; + + if (!avrule->parse_context) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return STATUS_ERR; + } + + *which_list = ((avrule->merged & QPOL_COND_RULE_LIST) ? 1 : 0); + + return STATUS_SUCCESS; +} |