mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-20 10:06:29 +00:00
Bounds: Convert to direct sepol structure use. Add iterator.
This commit is contained in:
parent
42ccafcdcc
commit
f39347d81f
@ -1,350 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* Defines the public interface for searching and iterating over the permissive types.
|
|
||||||
*
|
|
||||||
* @author Richard Haines richard_c_haines@btinternet.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 <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <qpol/iterator.h>
|
|
||||||
#include <qpol/policy.h>
|
|
||||||
#include <qpol/bounds_query.h>
|
|
||||||
#include <sepol/policydb/policydb.h>
|
|
||||||
#include "qpol_internal.h"
|
|
||||||
#include "iterator_internal.h"
|
|
||||||
|
|
||||||
/************ TYPEBOUNDS *************/
|
|
||||||
int qpol_typebounds_get_parent_name(const qpol_policy_t *policy, const qpol_typebounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
type_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (type_datum_t *)datum;
|
|
||||||
|
|
||||||
/* This will be zero if not a typebounds statement */
|
|
||||||
if (internal_datum->flavor == TYPE_TYPE && internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_type_val_to_name[internal_datum->bounds - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qpol_typebounds_get_child_name(const qpol_policy_t *policy, const qpol_typebounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
type_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (type_datum_t *)datum;
|
|
||||||
|
|
||||||
if (internal_datum->flavor == TYPE_TYPE && internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_type_val_to_name[internal_datum->s.value - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hash_state_next_typebounds(qpol_iterator_t * iter)
|
|
||||||
{
|
|
||||||
void *datum = NULL;
|
|
||||||
type_datum_t *internal_datum = NULL;
|
|
||||||
|
|
||||||
do {
|
|
||||||
hash_state_next(iter);
|
|
||||||
if (qpol_iterator_end(iter))
|
|
||||||
break;
|
|
||||||
|
|
||||||
qpol_iterator_get_item(iter, &datum);
|
|
||||||
internal_datum = (type_datum_t *) datum;
|
|
||||||
|
|
||||||
/* keep going on attributes */
|
|
||||||
if (internal_datum -> flavor != TYPE_TYPE)
|
|
||||||
continue;
|
|
||||||
/* keep going if type has no bounding */
|
|
||||||
} while (internal_datum->bounds == 0);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qpol_policy_get_typebounds_iter(const qpol_policy_t *policy, qpol_iterator_t **iter)
|
|
||||||
{
|
|
||||||
policydb_t *db;
|
|
||||||
int error = 0;
|
|
||||||
hash_state_t *hs = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || iter == NULL) {
|
|
||||||
if (iter != NULL)
|
|
||||||
*iter = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
hs = calloc(1, sizeof(hash_state_t));
|
|
||||||
if (hs == NULL) {
|
|
||||||
error = errno;
|
|
||||||
ERR(policy, "%s", strerror(ENOMEM));
|
|
||||||
errno = error;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
hs->table = &db->p_types.table;
|
|
||||||
hs->node = (*(hs->table))->htable[0];
|
|
||||||
|
|
||||||
if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur,
|
|
||||||
hash_state_next_typebounds, hash_state_end, hash_state_size, free, iter)) {
|
|
||||||
free(hs);
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hs->node == NULL)
|
|
||||||
hash_state_next_typebounds(*iter);
|
|
||||||
|
|
||||||
/* since we are iterating over all types, ensure our first item is actually bounded. */
|
|
||||||
if (!qpol_iterator_end(*iter)) {
|
|
||||||
void *datum = NULL;
|
|
||||||
type_datum_t *internal_datum = NULL;
|
|
||||||
|
|
||||||
qpol_iterator_get_item(*iter, &datum);
|
|
||||||
internal_datum = (type_datum_t *) datum;
|
|
||||||
|
|
||||||
if (internal_datum -> flavor != TYPE_TYPE || internal_datum->bounds == 0)
|
|
||||||
hash_state_next_typebounds(*iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************ ROLEBOUNDS *************/
|
|
||||||
int qpol_rolebounds_get_parent_name(const qpol_policy_t *policy, const qpol_rolebounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
role_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (role_datum_t *)datum;
|
|
||||||
|
|
||||||
/* This will be zero if not a rolebounds statement */
|
|
||||||
if (internal_datum->flavor == ROLE_ROLE && internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_role_val_to_name[internal_datum->bounds - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qpol_rolebounds_get_child_name(const qpol_policy_t *policy, const qpol_rolebounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
role_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (role_datum_t *)datum;
|
|
||||||
|
|
||||||
if (internal_datum->flavor == ROLE_ROLE && internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_role_val_to_name[internal_datum->s.value - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As rolebounds are in roles use these, however will need to calc number of bounds manually in top.tcl*/
|
|
||||||
int qpol_policy_get_rolebounds_iter(const qpol_policy_t *policy, qpol_iterator_t **iter)
|
|
||||||
{
|
|
||||||
policydb_t *db;
|
|
||||||
int error = 0;
|
|
||||||
hash_state_t *hs = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || iter == NULL) {
|
|
||||||
if (iter != NULL)
|
|
||||||
*iter = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
|
|
||||||
hs = calloc(1, sizeof(hash_state_t));
|
|
||||||
if (hs == NULL) {
|
|
||||||
error = errno;
|
|
||||||
ERR(policy, "%s", strerror(ENOMEM));
|
|
||||||
errno = error;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
hs->table = &db->p_roles.table;
|
|
||||||
hs->node = (*(hs->table))->htable[0];
|
|
||||||
|
|
||||||
if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur,
|
|
||||||
hash_state_next, hash_state_end, hash_state_size, free, iter)) {
|
|
||||||
free(hs);
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hs->node == NULL)
|
|
||||||
hash_state_next(*iter);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************ USERBOUNDS *************/
|
|
||||||
int qpol_userbounds_get_parent_name(const qpol_policy_t *policy, const qpol_userbounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
user_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (user_datum_t *)datum;
|
|
||||||
|
|
||||||
/* This will be zero if not a userbounds statement */
|
|
||||||
if (internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_user_val_to_name[internal_datum->bounds - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qpol_userbounds_get_child_name(const qpol_policy_t *policy, const qpol_userbounds_t * datum, const char **name)
|
|
||||||
{
|
|
||||||
user_datum_t *internal_datum = NULL;
|
|
||||||
policydb_t *db = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || datum == NULL || name == NULL) {
|
|
||||||
if (name != NULL)
|
|
||||||
*name = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
*name = NULL;
|
|
||||||
|
|
||||||
/* The bounds rules started in ver 24 */
|
|
||||||
if (!qpol_policy_has_capability(policy, QPOL_CAP_BOUNDS))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
internal_datum = (user_datum_t *)datum;
|
|
||||||
|
|
||||||
if (internal_datum->bounds != 0) {
|
|
||||||
*name = db->p_user_val_to_name[internal_datum->s.value - 1];
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As userbounds are in users use these, however will need to calc number of bounds manually in top.tcl*/
|
|
||||||
int qpol_policy_get_userbounds_iter(const qpol_policy_t *policy, qpol_iterator_t **iter)
|
|
||||||
{
|
|
||||||
policydb_t *db;
|
|
||||||
int error = 0;
|
|
||||||
hash_state_t *hs = NULL;
|
|
||||||
|
|
||||||
if (policy == NULL || iter == NULL) {
|
|
||||||
if (iter != NULL)
|
|
||||||
*iter = NULL;
|
|
||||||
ERR(policy, "%s", strerror(EINVAL));
|
|
||||||
errno = EINVAL;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
db = &policy->p->p;
|
|
||||||
|
|
||||||
hs = calloc(1, sizeof(hash_state_t));
|
|
||||||
if (hs == NULL) {
|
|
||||||
error = errno;
|
|
||||||
ERR(policy, "%s", strerror(ENOMEM));
|
|
||||||
errno = error;
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
hs->table = &db->p_users.table;
|
|
||||||
hs->node = (*(hs->table))->htable[0];
|
|
||||||
|
|
||||||
if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur,
|
|
||||||
hash_state_next, hash_state_end, hash_state_size, free, iter)) {
|
|
||||||
free(hs);
|
|
||||||
return STATUS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hs->node == NULL)
|
|
||||||
hash_state_next(*iter);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
# Copyright 2016, Tresys Technology, LLC
|
# Copyright 2016, Tresys Technology, LLC
|
||||||
# Copyright 2016-2017, Chris PeBenito <pebenito@ieee.org>
|
# Copyright 2016-2018, Chris PeBenito <pebenito@ieee.org>
|
||||||
#
|
#
|
||||||
# This file is part of SETools.
|
# This file is part of SETools.
|
||||||
#
|
#
|
||||||
@ -18,29 +18,6 @@
|
|||||||
# <http://www.gnu.org/licenses/>.
|
# <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
|
||||||
# Factory functions
|
|
||||||
#
|
|
||||||
cdef inline Bounds bounds_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol):
|
|
||||||
"""Factory function variant for iterating over Bounds objects."""
|
|
||||||
return bounds_factory(policy, <const qpol_typebounds_t *> symbol.obj)
|
|
||||||
|
|
||||||
|
|
||||||
cdef inline Bounds bounds_factory(SELinuxPolicy policy, const qpol_typebounds_t *symbol):
|
|
||||||
"""Factory function for creating Bounds objects."""
|
|
||||||
r = Bounds()
|
|
||||||
r.policy = policy
|
|
||||||
r.handle = symbol
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
#def validate_ruletype(t):
|
|
||||||
# """Validate *bounds rule types."""
|
|
||||||
# try:
|
|
||||||
# return BoundsRuletype.lookup(t)
|
|
||||||
# except KeyError as ex:
|
|
||||||
# raise exception.InvalidBoundsType("{0} is not a valid *bounds rule type.".format(t)) from ex
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Classes
|
# Classes
|
||||||
@ -54,13 +31,24 @@ class BoundsRuletype(PolicyEnum):
|
|||||||
|
|
||||||
cdef class Bounds(PolicySymbol):
|
cdef class Bounds(PolicySymbol):
|
||||||
|
|
||||||
"""A typebounds statement."""
|
"""A bounds statement."""
|
||||||
|
|
||||||
cdef const qpol_typebounds_t *handle
|
cdef:
|
||||||
cdef readonly object ruletype
|
readonly object ruletype
|
||||||
|
readonly object parent
|
||||||
|
readonly object child
|
||||||
|
|
||||||
def __init__(self):
|
@staticmethod
|
||||||
|
cdef factory(SELinuxPolicy policy, parent, child):
|
||||||
|
"""Factory function for creating Bounds objects."""
|
||||||
|
b = Bounds(parent, child)
|
||||||
|
b.policy = policy
|
||||||
|
return b
|
||||||
|
|
||||||
|
def __init__(self, parent, child):
|
||||||
self.ruletype = BoundsRuletype.typebounds
|
self.ruletype = BoundsRuletype.typebounds
|
||||||
|
self.parent = parent
|
||||||
|
self.child = child
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{0.ruletype} {0.parent} {0.child};".format(self)
|
return "{0.ruletype} {0.parent} {0.child};".format(self)
|
||||||
@ -68,29 +56,72 @@ cdef class Bounds(PolicySymbol):
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash("{0.ruletype}|{0.child};".format(self))
|
return hash("{0.ruletype}|{0.child};".format(self))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.policy == other.policy \
|
||||||
|
and self.ruletype == other.ruletype \
|
||||||
|
and self.parent == other.parent \
|
||||||
|
and self.child == other.child
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
# this is used by Python sorting functions
|
# this is used by Python sorting functions
|
||||||
return str(self) < str(other)
|
return str(self) < str(other)
|
||||||
|
|
||||||
def _eq(self, Bounds other):
|
|
||||||
"""Low-level equality check (C pointers)."""
|
|
||||||
return self.handle == other.handle
|
|
||||||
|
|
||||||
# TODO: look at qpol code to see if these functions
|
#
|
||||||
# can be converted to return symbols rather than names
|
# Iterators
|
||||||
@property
|
#
|
||||||
def parent(self):
|
cdef class TypeboundsIterator(HashtabIterator):
|
||||||
cdef const char *name
|
|
||||||
if qpol_typebounds_get_parent_name(self.policy.handle, self.handle, &name):
|
|
||||||
raise RuntimeError("Could not get parent name")
|
|
||||||
|
|
||||||
return self.policy.lookup_type(name)
|
"""Iterate over typebounds rules in the policy."""
|
||||||
|
|
||||||
@property
|
@staticmethod
|
||||||
def child(self):
|
cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table):
|
||||||
pass
|
"""Factory function for creating typebounds iterators."""
|
||||||
cdef const char *name
|
i = TypeboundsIterator()
|
||||||
if qpol_typebounds_get_child_name(self.policy.handle, self.handle, &name):
|
i.policy = policy
|
||||||
raise RuntimeError("Could not get child name")
|
i.table = table
|
||||||
|
i.reset()
|
||||||
|
return i
|
||||||
|
|
||||||
return self.policy.lookup_type(name)
|
def __next__(self):
|
||||||
|
cdef sepol.type_datum_t *datum
|
||||||
|
super().__next__()
|
||||||
|
|
||||||
|
datum = <sepol.type_datum_t *> self.curr.datum
|
||||||
|
while datum.flavor != sepol.TYPE_TYPE or datum.bounds == 0:
|
||||||
|
super().__next__()
|
||||||
|
datum = <sepol.type_datum_t *> self.curr.datum
|
||||||
|
|
||||||
|
return Bounds.factory(self.policy,
|
||||||
|
Type.factory(self.policy, self.policy.handle.p.p.type_val_to_struct[datum.bounds - 1]),
|
||||||
|
Type.factory(self.policy, datum))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
cdef sepol.type_datum_t *datum
|
||||||
|
cdef sepol.hashtab_node_t *node
|
||||||
|
cdef uint32_t bucket = 0
|
||||||
|
cdef size_t count = 0
|
||||||
|
|
||||||
|
while bucket < self.table[0].size:
|
||||||
|
node = self.table[0].htable[bucket]
|
||||||
|
while node != NULL:
|
||||||
|
datum = <sepol.type_datum_t *>node.datum if node else NULL
|
||||||
|
if datum != NULL and datum.flavor == sepol.TYPE_TYPE and datum.bounds != 0:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
node = node.next
|
||||||
|
|
||||||
|
bucket += 1
|
||||||
|
|
||||||
|
return count
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
cdef sepol.type_datum_t * datum
|
||||||
|
|
||||||
|
super().reset()
|
||||||
|
|
||||||
|
# advance over any attributes or aliases
|
||||||
|
datum = <sepol.type_datum_t *> self.node.datum
|
||||||
|
while datum != NULL and datum.flavor != sepol.TYPE_TYPE and datum.bounds == 0:
|
||||||
|
self._next_node()
|
||||||
|
datum = <sepol.type_datum_t *> self.node.datum
|
||||||
|
@ -419,8 +419,7 @@ cdef class SELinuxPolicy:
|
|||||||
@property
|
@property
|
||||||
def typebounds_count(self):
|
def typebounds_count(self):
|
||||||
"""The number of typebounds rules."""
|
"""The number of typebounds rules."""
|
||||||
return sum(1 for b in self.bounds()
|
return len(TypeboundsIterator.factory(self, &self.handle.p.p.symtab[sepol.SYM_TYPES].table))
|
||||||
if b.ruletype == BoundsRuletype.typebounds)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def user_count(self):
|
def user_count(self):
|
||||||
@ -540,11 +539,7 @@ cdef class SELinuxPolicy:
|
|||||||
|
|
||||||
def bounds(self):
|
def bounds(self):
|
||||||
"""Iterator which yields all *bounds statements (typebounds, etc.)"""
|
"""Iterator which yields all *bounds statements (typebounds, etc.)"""
|
||||||
cdef qpol_iterator_t *iter
|
return TypeboundsIterator.factory(self, &self.handle.p.p.symtab[sepol.SYM_TYPES].table)
|
||||||
if qpol_policy_get_typebounds_iter(self.handle, &iter):
|
|
||||||
raise MemoryError
|
|
||||||
|
|
||||||
return qpol_iterator_factory(self, iter, bounds_factory_iter)
|
|
||||||
|
|
||||||
def categories(self):
|
def categories(self):
|
||||||
"""Iterator which yields all MLS categories."""
|
"""Iterator which yields all MLS categories."""
|
||||||
|
1
setup.py
1
setup.py
@ -67,7 +67,6 @@ else:
|
|||||||
ext_py_mods = [Extension('setools.policyrep.libpolicyrep',
|
ext_py_mods = [Extension('setools.policyrep.libpolicyrep',
|
||||||
['setools/policyrep/libpolicyrep.pyx',
|
['setools/policyrep/libpolicyrep.pyx',
|
||||||
'libqpol/avrule_query.c',
|
'libqpol/avrule_query.c',
|
||||||
'libqpol/bounds_query.c',
|
|
||||||
'libqpol/class_perm_query.c',
|
'libqpol/class_perm_query.c',
|
||||||
'libqpol/cond_query.c',
|
'libqpol/cond_query.c',
|
||||||
'libqpol/constraint_query.c',
|
'libqpol/constraint_query.c',
|
||||||
|
Loading…
Reference in New Issue
Block a user