diff --git a/libqpol/ftrule_query.c b/libqpol/ftrule_query.c deleted file mode 100644 index 82bff7d..0000000 --- a/libqpol/ftrule_query.c +++ /dev/null @@ -1,300 +0,0 @@ -/** - * @file - * Defines public interface for iterating over filename transition rules. - * - * @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 -#include -#include -#include -#include "iterator_internal.h" -#include "qpol_internal.h" -#include -#include - -typedef struct filename_trans_state -{ - unsigned int bucket; - hashtab_ptr_t cur_item; - filename_trans_t *cur; -} filename_trans_state_t; - -static int filename_trans_state_end(const qpol_iterator_t * iter) -{ - filename_trans_state_t *fts = NULL; - - if (!iter || !(fts = qpol_iterator_state(iter))) { - errno = EINVAL; - return STATUS_ERR; - } - - return fts->cur ? 0 : 1; -} - -static void *filename_trans_state_get_cur(const qpol_iterator_t * iter) -{ - filename_trans_state_t *fts = NULL; - const policydb_t *db = NULL; - - if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter)) || filename_trans_state_end(iter)) { - errno = EINVAL; - return NULL; - } - - return fts->cur; -} - -static int filename_trans_state_next(qpol_iterator_t * iter) -{ - filename_trans_state_t *fts = NULL; - const policydb_t *db = NULL; - - if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { - errno = EINVAL; - return STATUS_ERR; - } - - if (filename_trans_state_end(iter)) { - errno = ERANGE; - return STATUS_ERR; - } - - fts->cur_item = fts->cur_item->next; - while (fts->cur_item == NULL) { - fts->bucket++; - if (fts->bucket >= db->filename_trans->size) { - break; - } - - fts->cur_item = db->filename_trans->htable[fts->bucket]; - } - - if (fts->cur_item == NULL) { - fts->cur = NULL; - } else { - fts->cur = (filename_trans_t*)fts->cur_item->key; - } - - return STATUS_SUCCESS; -} - -static size_t filename_trans_state_size(const qpol_iterator_t * iter) -{ - filename_trans_state_t *fts = NULL; - const policydb_t *db = NULL; - size_t count = 0; - unsigned int i = 0; - - if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { - errno = EINVAL; - return 0; - } - - hashtab_ptr_t cur = NULL; - for (i = 0; i < db->filename_trans->size; i++) { - cur = db->filename_trans->htable[i]; - while (cur != NULL) { - count++; - cur = cur->next; - } - } - - return count; -} - -int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) -{ - policydb_t *db = NULL; - filename_trans_state_t *fts = NULL; - int error = 0; - - if (iter) - *iter = NULL; - - if (!policy || !iter) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - - fts = calloc(1, sizeof(filename_trans_state_t)); - if (!fts) { - /* errno set by calloc */ - ERR(policy, "%s", strerror(errno)); - return STATUS_ERR; - } - - fts->bucket = 0; - fts->cur_item = db->filename_trans->htable[0]; - fts->cur = NULL; - - fts->cur_item = db->filename_trans->htable[fts->bucket]; - while (fts->cur_item == NULL) { - fts->bucket++; - if (fts->bucket >= db->filename_trans->size) { - break; - } - - fts->cur_item = db->filename_trans->htable[fts->bucket]; - } - - if (fts->cur_item != NULL) { - fts->cur = (filename_trans_t*)fts->cur_item->key; - } - - if (qpol_iterator_create - (policy, (void *)fts, filename_trans_state_get_cur, filename_trans_state_next, filename_trans_state_end, filename_trans_state_size, - free, iter)) { - error = errno; - free(fts); - errno = error; - return STATUS_ERR; - } - - return STATUS_SUCCESS; -} - -int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** source) -{ - policydb_t *db = NULL; - filename_trans_t *ft = NULL; - - if (source) { - *source = NULL; - } - - if (!policy || !rule || !source) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - ft = (filename_trans_t *) rule; - - *source = (qpol_type_t *) db->type_val_to_struct[ft->stype - 1]; - - return STATUS_SUCCESS; -} - -int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** target) -{ - policydb_t *db = NULL; - filename_trans_t *ft = NULL; - - if (target) { - *target = NULL; - } - - if (!policy || !rule || !target) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - ft = (filename_trans_t *) rule; - - *target = (qpol_type_t *) db->type_val_to_struct[ft->ttype - 1]; - - return STATUS_SUCCESS; -} - -int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, - const qpol_class_t ** obj_class) -{ - policydb_t *db = NULL; - filename_trans_t *ft = 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; - ft = (filename_trans_t *) rule; - - *obj_class = (qpol_class_t *) db->class_val_to_struct[ft->tclass - 1]; - - return STATUS_SUCCESS; -} - -int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** dflt) -{ - policydb_t *db = NULL; - filename_trans_t *ft = NULL; - - if (dflt) { - *dflt = NULL; - } - - if (!policy || !rule || !dflt) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - ft = (filename_trans_t *) rule; - - /* Since the filename_trans rules were converted to being stored in a hashtab, otype was moved to the datum of the hashtab. - * So we just look it up here. - */ - filename_trans_datum_t *datum = hashtab_search(db->filename_trans, (hashtab_key_t)ft); - - if (datum == NULL) { - return STATUS_ERR; - } - - *dflt = (qpol_type_t *) db->type_val_to_struct[datum->otype - 1]; - - return STATUS_SUCCESS; -} - -int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name) -{ - filename_trans_t *ft = NULL; - - if (name) { - *name = NULL; - } - - if (!policy || !rule || !name) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - ft = (filename_trans_t *) rule; - - *name = ft->name; - - return STATUS_SUCCESS; -} - diff --git a/setools/policyrep/libpolicyrep.pyx b/setools/policyrep/libpolicyrep.pyx index a21a677..3e93d42 100644 --- a/setools/policyrep/libpolicyrep.pyx +++ b/setools/policyrep/libpolicyrep.pyx @@ -176,16 +176,6 @@ cdef extern from "include/qpol/constraint_query.h": int qpol_class_get_constraint_iter(const qpol_policy_t * policy, const qpol_class_t * obj_class, qpol_iterator_t ** constr) int qpol_class_get_validatetrans_iter(const qpol_policy_t * policy, const qpol_class_t * obj_class, qpol_iterator_t ** vtrans) -cdef extern from "include/qpol/ftrule_query.h": - ctypedef struct qpol_filename_trans_t: - pass - int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) - int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** source) - int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** target) - int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** dflt) - int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_class_t ** obj_class) - int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name) - cdef extern from "include/qpol/iterator.h": ctypedef struct qpol_iterator_t: pass diff --git a/setools/policyrep/selinuxpolicy.pxi b/setools/policyrep/selinuxpolicy.pxi index d72dead..6cdcd40 100644 --- a/setools/policyrep/selinuxpolicy.pxi +++ b/setools/policyrep/selinuxpolicy.pxi @@ -643,12 +643,9 @@ cdef class SELinuxPolicy: if qpol_policy_get_terule_iter(self.handle, te_rule_types, &te_iter): raise MemoryError - if qpol_policy_get_filename_trans_iter(self.handle, &ft_iter): - raise MemoryError - return chain(qpol_iterator_factory(self, av_iter, avrule_factory_iter), qpol_iterator_factory(self, te_iter, terule_factory_iter), - qpol_iterator_factory(self, ft_iter, filename_terule_factory_iter)) + FileNameTERuleIterator.factory(self, &self.handle.p.p.filename_trans)) # # Constraints iterators diff --git a/setools/policyrep/terule.pxi b/setools/policyrep/terule.pxi index c336896..bf59255 100644 --- a/setools/policyrep/terule.pxi +++ b/setools/policyrep/terule.pxi @@ -1,5 +1,5 @@ # Copyright 2014-2016, Tresys Technology, LLC -# Copyright 2016-2017, Chris PeBenito +# Copyright 2016-2018, Chris PeBenito # # This file is part of SETools. # @@ -69,20 +69,6 @@ cdef inline TERule terule_factory(SELinuxPolicy policy, const qpol_terule_t *sym r.handle = symbol return r -# -# Filename TE rule factory functions -# -cdef inline FileNameTERule filename_terule_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol): - """Factory function variant for iterating over FileNameTERule objects.""" - return filename_terule_factory(policy, symbol.obj) - -cdef inline FileNameTERule filename_terule_factory(SELinuxPolicy policy, const qpol_filename_trans_t *symbol): - """Factory function for creating TERule objects.""" - r = FileNameTERule() - r.policy = policy - r.handle = symbol - return r - # # Extended permission set iterator factory function # @@ -629,11 +615,21 @@ cdef class FileNameTERule(PolicyRule): """A type_transition type enforcement rule with filename.""" cdef: - const qpol_filename_trans_t *handle + sepol.filename_trans_t *handle readonly object ruletype + Type dft - def __init__(self): + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.filename_trans_t *symbol, sepol.type_datum_t *dft): + """Factory function for creating TERule objects.""" + r = FileNameTERule(Type.factory(policy, dft)) + r.policy = policy + r.handle = symbol + return r + + def __init__(self, dft): self.ruletype = TERuletype.type_transition + self.dft = dft def __str__(self): rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default} {0.filename};". \ @@ -667,7 +663,7 @@ cdef class FileNameTERule(PolicyRule): def __deepcopy__(self, memo): # shallow copy as all of the members are immutable - newobj = filename_terule_factory(self.policy, self.handle) + newobj = FileNameTERule.factory(self.policy, self.handle, self.dft.handle) memo[id(self)] = newobj return newobj @@ -682,7 +678,7 @@ cdef class FileNameTERule(PolicyRule): return (self.handle) cdef _unpickle(self, bytes handle): - memcpy(&self.handle, handle, sizeof(qpol_filename_trans_t*)) + memcpy(&self.handle, handle, sizeof(sepol.filename_trans_t*)) def _eq(self, FileNameTERule other): """Low-level equality check (C pointers).""" @@ -711,27 +707,12 @@ cdef class FileNameTERule(PolicyRule): @property def default(self): """The rule's default type.""" - cdef sepol.filename_trans_datum_t *datum - datum = hashtab_search( - self.policy.handle.p.p.filename_trans, self.handle) - - if datum == NULL: - raise LowLevelPolicyError("Error reading default type for TE rule.") - - return Type.factory(self.policy, - self.policy.handle.p.p.type_val_to_struct[datum.otype - 1]) + return self.dft @property def filename(self): """The type_transition rule's file name.""" - cdef const char *name - if qpol_filename_trans_get_filename(self.policy.handle, self.handle, &name): - ex = LowLevelPolicyError("Error reading file name for type_transition rule: {}". - format(strerror(errno))) - ex.errno = errno - raise ex - - return intern(name) + return intern(self.handle.name) def expand(self): """Expand the rule into an equivalent set of rules without attributes.""" @@ -837,3 +818,25 @@ cdef class ExpandedFileNameTERule(FileNameTERule): def __lt__(self, other): return str(self) < str(other) + + +# +# Iterators +# +cdef class FileNameTERuleIterator(HashtabIterator): + + """Iterate over FileNameTERules in the policy.""" + + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table): + """Factory function for creating FileNameTERule iterators.""" + i = FileNameTERuleIterator() + i.policy = policy + i.table = table + i.reset() + return i + + def __next__(self): + super().__next__() + return FileNameTERule.factory(self.policy, self.curr.key, + self.curr.datum) diff --git a/setup.py b/setup.py index de2ece9..588f3af 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,6 @@ ext_py_mods = [Extension('setools.policyrep.libpolicyrep', 'libqpol/class_perm_query.c', 'libqpol/cond_query.c', 'libqpol/constraint_query.c', - 'libqpol/ftrule_query.c', 'libqpol/iterator.c', 'libqpol/policy.c', 'libqpol/policy_extend.c',