mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
policyrep: Convert type and typeattrs to direct sepol structure access.
Add iterators.
This commit is contained in:
parent
9eba422499
commit
c45205c5b0
@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* Defines the public interface for searching and iterating over the permissive types.
|
||||
*
|
||||
* @author Steve Lawrence slawrence@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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <qpol/iterator.h>
|
||||
#include <qpol/policy.h>
|
||||
#include <qpol/permissive_query.h>
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include "qpol_internal.h"
|
||||
#include "iterator_internal.h"
|
||||
|
||||
|
||||
int qpol_permissive_get_name(const qpol_policy_t *policy, const qpol_permissive_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;
|
||||
}
|
||||
|
||||
db = &policy->p->p;
|
||||
internal_datum = (type_datum_t *)datum;
|
||||
|
||||
*name = db->p_type_val_to_name[internal_datum->s.value - 1];
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_policy_get_permissive_iter(const qpol_policy_t *policy, qpol_iterator_t **iter)
|
||||
{
|
||||
int error = 0;
|
||||
policydb_t *db;
|
||||
ebitmap_state_t *state = NULL;
|
||||
|
||||
if (iter) {
|
||||
*iter = NULL;
|
||||
}
|
||||
|
||||
if (policy == NULL || iter == NULL) {
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
db = &policy->p->p;
|
||||
|
||||
state = calloc(1, sizeof(ebitmap_state_t));
|
||||
if (state == NULL) {
|
||||
error = errno;
|
||||
ERR(policy, "%s", strerror(ENOMEM));
|
||||
errno = error;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
state->bmap = &(db->permissive_map);
|
||||
state->cur = state->bmap->node ? state->bmap->node->startbit : 0;
|
||||
|
||||
if (qpol_iterator_create(policy, state, ebitmap_state_get_cur_permissive,
|
||||
ebitmap_state_next, ebitmap_state_end, ebitmap_state_size, free, iter)) {
|
||||
free(state);
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (state->bmap->node && !ebitmap_get_bit(state->bmap, state->cur))
|
||||
ebitmap_state_next(*iter);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
@ -55,11 +55,12 @@ struct extend_bogus_alias_struct
|
||||
static int extend_find_bogus_alias(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *args)
|
||||
{
|
||||
struct extend_bogus_alias_struct *e = (struct extend_bogus_alias_struct *)args;
|
||||
/* within libqpol, qpol_type_t is the same a libsepol's type_datum_t */
|
||||
qpol_type_t *qtype = (qpol_type_t *) datum;
|
||||
type_datum_t *type = (type_datum_t *) datum;
|
||||
unsigned char isalias;
|
||||
qpol_type_get_isalias(e->q, qtype, &isalias);
|
||||
|
||||
unsigned char isalias = 0;
|
||||
if ((type->primary == 0 && type->flavor == TYPE_TYPE) || type->flavor == TYPE_ALIAS)
|
||||
isalias = 1;
|
||||
|
||||
return isalias && type->s.value == 0;
|
||||
}
|
||||
|
||||
@ -97,11 +98,9 @@ static int qpol_policy_remove_bogus_aliases(qpol_policy_t * policy)
|
||||
struct extend_bogus_alias_struct e = { policy, 0 };
|
||||
hashtab_map_remove_on_error(db->p_types.table, extend_find_bogus_alias, extend_remove_bogus_alias, &e);
|
||||
|
||||
#ifdef SETOOLS_DEBUG
|
||||
if (e.num_bogus_aliases > 0) {
|
||||
WARN(policy, "%s", "This policy contained disabled aliases; they have been removed.");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -518,9 +517,6 @@ int policy_extend(qpol_policy_t * policy)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (policy->options & QPOL_POLICY_OPTION_NO_RULES)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
retv = qpol_policy_add_cond_rule_traceback(policy);
|
||||
if (retv) {
|
||||
error = errno;
|
||||
|
@ -1,468 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* Implementation of the interface for searching and iterating over types.
|
||||
*
|
||||
* @author Jeremy A. Mowery jmowery@tresys.com
|
||||
* @author Jason Tang jtang@tresys.com
|
||||
*
|
||||
* Copyright (C) 2006-2008 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 <config.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <qpol/iterator.h>
|
||||
#include <qpol/policy.h>
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include "iterator_internal.h"
|
||||
#include <qpol/type_query.h>
|
||||
#include "qpol_internal.h"
|
||||
|
||||
int qpol_policy_get_type_by_name(const qpol_policy_t * policy, const char *name, const qpol_type_t ** datum)
|
||||
{
|
||||
hashtab_datum_t internal_datum;
|
||||
policydb_t *db;
|
||||
|
||||
if (policy == NULL || name == NULL || datum == NULL) {
|
||||
if (datum != NULL)
|
||||
*datum = NULL;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
db = &policy->p->p;
|
||||
internal_datum = hashtab_search(db->p_types.table, (hashtab_key_t)name);
|
||||
if (internal_datum == NULL) {
|
||||
*datum = NULL;
|
||||
ERR(policy, "could not find datum for type %s", name);
|
||||
errno = ENOENT;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
*datum = (qpol_type_t *) internal_datum;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_policy_get_type_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, hash_state_end, hash_state_size, free, iter)) {
|
||||
free(hs);
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (hs->node == NULL)
|
||||
hash_state_next(*iter);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_value(const qpol_policy_t * policy, const qpol_type_t * datum, uint32_t * value)
|
||||
{
|
||||
type_datum_t *internal_datum;
|
||||
|
||||
if (policy == NULL || datum == NULL || value == NULL) {
|
||||
if (value != NULL)
|
||||
*value = 0;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
if (internal_datum->flavor == TYPE_ALIAS) {
|
||||
/* aliases that came from modules should use the value
|
||||
* referenced to by that alias */
|
||||
*value = internal_datum->primary;
|
||||
} else {
|
||||
*value = internal_datum->s.value;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a type_datum_t is an alias or a non-alias (primary
|
||||
* type or an attribute). For aliases declared in base policies, they
|
||||
* will have no primary value and a flavor of TYPE_TYPE. For aliases
|
||||
* declared in modules, they have a flavor of TYPE_ALIAS; their
|
||||
* primary value points to the new /linked/ type's value.
|
||||
*
|
||||
* @param datum Type datum to check.
|
||||
*
|
||||
* @return 1 if the datum is an alias, 0 if not.
|
||||
*/
|
||||
static int is_type_really_an_alias(const type_datum_t * datum)
|
||||
{
|
||||
if (datum->primary == 0 && datum->flavor == TYPE_TYPE) {
|
||||
return 1;
|
||||
}
|
||||
if (datum->flavor == TYPE_ALIAS) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qpol_type_get_isalias(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *isalias)
|
||||
{
|
||||
type_datum_t *internal_datum;
|
||||
|
||||
if (policy == NULL || datum == NULL || isalias == NULL) {
|
||||
if (isalias != NULL)
|
||||
*isalias = 0;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
*isalias = is_type_really_an_alias(internal_datum);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_isattr(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *isattr)
|
||||
{
|
||||
type_datum_t *internal_datum;
|
||||
|
||||
if (policy == NULL || datum == NULL || isattr == NULL) {
|
||||
if (isattr != NULL)
|
||||
*isattr = 0;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
*isattr = (internal_datum->flavor == TYPE_ATTRIB ? 1 : 0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_ispermissive(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *ispermissive)
|
||||
{
|
||||
if (policy == NULL || datum == NULL || ispermissive == NULL) {
|
||||
if (ispermissive != NULL)
|
||||
*ispermissive = 0;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
#ifdef HAVE_SEPOL_PERMISSIVE_TYPES
|
||||
/* checking internal_datum->flags for permissive won't work,
|
||||
because the type could be an alias. so instead, look up
|
||||
its value within the permissive map */
|
||||
uint32_t value;
|
||||
if (qpol_type_get_value(policy, datum, &value) < 0) {
|
||||
return STATUS_ERR;
|
||||
}
|
||||
policydb_t *p = &policy->p->p;
|
||||
/* note that unlike other bitmaps, this one does not subtract
|
||||
1 in the bitmap */
|
||||
*ispermissive = ebitmap_get_bit(&p->permissive_map, value);
|
||||
#else
|
||||
*ispermissive = 0;
|
||||
#endif
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_type_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** types)
|
||||
{
|
||||
type_datum_t *internal_datum = NULL;
|
||||
ebitmap_state_t *es = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (types != NULL)
|
||||
*types = NULL;
|
||||
|
||||
if (policy == NULL || datum == NULL || types == NULL) {
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
|
||||
if (internal_datum->flavor != TYPE_ATTRIB) {
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_NODATA;
|
||||
}
|
||||
|
||||
es = calloc(1, sizeof(ebitmap_state_t));
|
||||
if (es == NULL) {
|
||||
error = errno;
|
||||
ERR(policy, "%s", strerror(ENOMEM));
|
||||
errno = error;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
es->bmap = &(internal_datum->types);
|
||||
es->cur = es->bmap->node ? es->bmap->node->startbit : 0;
|
||||
|
||||
if (qpol_iterator_create(policy, es, ebitmap_state_get_cur_type,
|
||||
ebitmap_state_next, ebitmap_state_end, ebitmap_state_size, free, types)) {
|
||||
free(es);
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (es->bmap->node && !ebitmap_get_bit(es->bmap, es->cur))
|
||||
ebitmap_state_next(*types);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_attr_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** attrs)
|
||||
{
|
||||
type_datum_t *internal_datum = NULL;
|
||||
ebitmap_state_t *es = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (attrs != NULL)
|
||||
*attrs = NULL;
|
||||
|
||||
if (policy == NULL || datum == NULL || attrs == NULL) {
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
|
||||
if (internal_datum->flavor == TYPE_ATTRIB) {
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_NODATA;
|
||||
}
|
||||
|
||||
es = calloc(1, sizeof(ebitmap_state_t));
|
||||
if (es == NULL) {
|
||||
error = errno;
|
||||
ERR(policy, "%s", strerror(ENOMEM));
|
||||
errno = error;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
es->bmap = &(internal_datum->types);
|
||||
es->cur = es->bmap->node ? es->bmap->node->startbit : 0;
|
||||
|
||||
if (qpol_iterator_create(policy, es, ebitmap_state_get_cur_type,
|
||||
ebitmap_state_next, ebitmap_state_end, ebitmap_state_size, free, attrs)) {
|
||||
free(es);
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (es->bmap->node && !ebitmap_get_bit(es->bmap, es->cur))
|
||||
ebitmap_state_next(*attrs);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int qpol_type_get_name(const qpol_policy_t * policy, const qpol_type_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;
|
||||
}
|
||||
|
||||
db = &policy->p->p;
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
|
||||
*name = db->p_type_val_to_name[internal_datum->s.value - 1];
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct type_alias_hash_state
|
||||
{
|
||||
unsigned int bucket;
|
||||
hashtab_node_t *node;
|
||||
hashtab_t *table;
|
||||
uint32_t val;
|
||||
} type_alias_hash_state_t;
|
||||
|
||||
/**
|
||||
* For aliases that came from the base policy, their primary type is
|
||||
* referenced by s.value. For aliases that came from modules, their
|
||||
* primary type is referenced by the primary field.
|
||||
*
|
||||
* @param datum Alias whose primary value to get.
|
||||
*
|
||||
* @return The primary type's identifier.
|
||||
*/
|
||||
static uint32_t get_alias_primary(const type_datum_t * datum)
|
||||
{
|
||||
if (datum->flavor == TYPE_TYPE) {
|
||||
return datum->s.value;
|
||||
} else {
|
||||
return datum->primary;
|
||||
}
|
||||
}
|
||||
|
||||
static int hash_state_next_type_alias(qpol_iterator_t * iter)
|
||||
{
|
||||
type_alias_hash_state_t *hs = NULL;
|
||||
type_datum_t *datum = NULL;
|
||||
|
||||
if (iter == NULL) {
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
hs = (type_alias_hash_state_t *) qpol_iterator_state(iter);
|
||||
if (hs == NULL) {
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (hs->bucket >= (*(hs->table))->size) {
|
||||
errno = ERANGE;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
do {
|
||||
hash_state_next(iter);
|
||||
datum = hs->node ? (type_datum_t *) hs->node->datum : NULL;
|
||||
} while (datum != NULL && (hs->val != get_alias_primary(datum) || !is_type_really_an_alias(datum)));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void *hash_state_get_cur_alias(const qpol_iterator_t * iter)
|
||||
{
|
||||
type_alias_hash_state_t *hs = NULL;
|
||||
|
||||
if (iter == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
hs = (type_alias_hash_state_t *) qpol_iterator_state(iter);
|
||||
if (hs == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hs->bucket >= (*(hs->table))->size) {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hs->node->key;
|
||||
}
|
||||
|
||||
static size_t hash_alias_state_size(const qpol_iterator_t * iter)
|
||||
{
|
||||
type_alias_hash_state_t *hs = NULL;
|
||||
type_datum_t *tmp_datum;
|
||||
hashtab_node_t *tmp_node;
|
||||
uint32_t tmp_bucket = 0;
|
||||
size_t count = 0;
|
||||
|
||||
if (iter == NULL || qpol_iterator_state(iter) == NULL) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hs = (type_alias_hash_state_t *) qpol_iterator_state(iter);
|
||||
|
||||
for (tmp_bucket = 0; tmp_bucket < (*(hs->table))->size; tmp_bucket++) {
|
||||
for (tmp_node = (*(hs->table))->htable[tmp_bucket]; tmp_node; tmp_node = tmp_node->next) {
|
||||
tmp_datum = tmp_node ? tmp_node->datum : NULL;
|
||||
if (tmp_datum) {
|
||||
if (hs->val == get_alias_primary(tmp_datum) && is_type_really_an_alias(tmp_datum)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int qpol_type_get_alias_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** aliases)
|
||||
{
|
||||
type_datum_t *internal_datum = NULL;
|
||||
policydb_t *db = NULL;
|
||||
int error = 0;
|
||||
type_alias_hash_state_t *hs = NULL;
|
||||
|
||||
if (policy == NULL || datum == NULL || aliases == NULL) {
|
||||
if (aliases != NULL)
|
||||
*aliases = NULL;
|
||||
ERR(policy, "%s", strerror(EINVAL));
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
db = &policy->p->p;
|
||||
internal_datum = (type_datum_t *) datum;
|
||||
|
||||
hs = calloc(1, sizeof(type_alias_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];
|
||||
hs->val = get_alias_primary(internal_datum);
|
||||
|
||||
if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur_alias,
|
||||
hash_state_next_type_alias, hash_state_end, hash_alias_state_size, free, aliases)) {
|
||||
free(hs);
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
if (hs->node == NULL || hs->val != get_alias_primary((type_datum_t *) (hs->node->datum)) ||
|
||||
!is_type_really_an_alias((type_datum_t *) hs->node->datum))
|
||||
hash_state_next_type_alias(*aliases);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
@ -84,7 +84,7 @@ cdef class Bounds(PolicySymbol):
|
||||
if qpol_typebounds_get_parent_name(self.policy.handle, self.handle, &name):
|
||||
raise RuntimeError("Could not get parent name")
|
||||
|
||||
return type_factory_lookup(self.policy, name, False)
|
||||
return self.policy.lookup_type(name)
|
||||
|
||||
@property
|
||||
def child(self):
|
||||
@ -93,4 +93,4 @@ cdef class Bounds(PolicySymbol):
|
||||
if qpol_typebounds_get_child_name(self.policy.handle, self.handle, &name):
|
||||
raise RuntimeError("Could not get child name")
|
||||
|
||||
return type_factory_lookup(self.policy, name, False)
|
||||
return self.policy.lookup_type(name)
|
||||
|
@ -450,7 +450,7 @@ cdef class ConstraintExprNode(PolicySymbol):
|
||||
if self.symbol_type in self._role_syms:
|
||||
names = frozenset(role_factory_lookup(self.policy, r) for r in name_iterator)
|
||||
elif self.symbol_type in self._type_syms:
|
||||
names = frozenset(type_or_attr_factory_lookup(self.policy, t, False)
|
||||
names = frozenset(self.policy.lookup_type_or_attr(t)
|
||||
for t in name_iterator)
|
||||
else:
|
||||
names = frozenset(user_factory_lookup(self.policy, u) for u in name_iterator)
|
||||
|
@ -63,11 +63,8 @@ cdef class Context(PolicySymbol):
|
||||
@property
|
||||
def type_(self):
|
||||
"""The type portion of the context."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_context_get_type(self.policy.handle, self.handle, &t):
|
||||
raise RuntimeError("Could not get type from context")
|
||||
|
||||
return type_factory(self.policy, t, False)
|
||||
cdef sepol.type_datum_t *t = self.policy.handle.p.p.type_val_to_struct[self.handle.type - 1]
|
||||
return Type.factory(self.policy, t)
|
||||
|
||||
@property
|
||||
def range_(self):
|
||||
|
@ -314,16 +314,6 @@ cdef extern from "include/qpol/terule_query.h":
|
||||
cdef extern from "include/qpol/type_query.h":
|
||||
ctypedef struct qpol_type_t:
|
||||
pass
|
||||
int qpol_policy_get_type_by_name(const qpol_policy_t * policy, const char *name, const qpol_type_t ** datum)
|
||||
int qpol_policy_get_type_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter)
|
||||
int qpol_type_get_value(const qpol_policy_t * policy, const qpol_type_t * datum, uint32_t * value)
|
||||
int qpol_type_get_isalias(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *isalias)
|
||||
int qpol_type_get_isattr(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *isattr)
|
||||
int qpol_type_get_ispermissive(const qpol_policy_t * policy, const qpol_type_t * datum, unsigned char *ispermissive)
|
||||
int qpol_type_get_type_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** types)
|
||||
int qpol_type_get_attr_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** attrs)
|
||||
int qpol_type_get_name(const qpol_policy_t * policy, const qpol_type_t * datum, const char **name)
|
||||
int qpol_type_get_alias_iter(const qpol_policy_t * policy, const qpol_type_t * datum, qpol_iterator_t ** aliases)
|
||||
|
||||
cdef extern from "include/qpol/user_query.h":
|
||||
ctypedef struct qpol_user_t:
|
||||
|
@ -83,26 +83,12 @@ cdef class MLSRule(PolicyRule):
|
||||
@property
|
||||
def source(self):
|
||||
"""The rule's source type/attribute."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_range_trans_get_source_type(self.policy.handle, self.handle, &t):
|
||||
ex = LowLevelPolicyError("Error reading source type/attr for range_transition rule: {}".
|
||||
format(strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, self.policy.handle.p.p.type_val_to_struct[self.handle.source_type - 1])
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
"""The rule's target type/attribute."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_range_trans_get_target_type(self.policy.handle, self.handle, &t):
|
||||
ex = LowLevelPolicyError("Error reading target type/attr for range_transition rule: {}".
|
||||
format(strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, self.policy.handle.p.p.type_val_to_struct[self.handle.target_type - 1])
|
||||
|
||||
@property
|
||||
def tclass(self):
|
||||
|
@ -183,7 +183,7 @@ cdef class RoleTransition(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, <sepol.type_datum_t *>t)
|
||||
|
||||
@property
|
||||
def tclass(self):
|
||||
|
@ -395,7 +395,7 @@ cdef class SELinuxPolicy:
|
||||
@property
|
||||
def type_attribute_count(self):
|
||||
"""The number of (type) attributes."""
|
||||
return sum(1 for _ in self.typeattributes())
|
||||
return len(self.typeattributes())
|
||||
|
||||
@property
|
||||
def type_change_count(self):
|
||||
@ -406,7 +406,7 @@ cdef class SELinuxPolicy:
|
||||
@property
|
||||
def type_count(self):
|
||||
"""The number of types."""
|
||||
return sum(1 for _ in self.types())
|
||||
return len(self.types())
|
||||
|
||||
@property
|
||||
def type_member_count(self):
|
||||
@ -501,15 +501,27 @@ cdef class SELinuxPolicy:
|
||||
|
||||
def lookup_type(self, name):
|
||||
"""Look up a type by name."""
|
||||
return type_factory_lookup(self, name, True)
|
||||
for t in self.types():
|
||||
if t == name:
|
||||
return t
|
||||
|
||||
raise InvalidType("{0} is not a valid type".format(name))
|
||||
|
||||
def lookup_type_or_attr(self, name):
|
||||
"""Look up a type or type attribute by name."""
|
||||
return type_or_attr_factory_lookup(self, name, True)
|
||||
for t in chain(self.types(), self.typeattributes()):
|
||||
if t == name:
|
||||
return t
|
||||
|
||||
raise InvalidType("{0} is not a valid type attribute".format(name))
|
||||
|
||||
def lookup_typeattr(self, name):
|
||||
"""Look up a type attribute by name."""
|
||||
return attribute_factory_lookup(self, name)
|
||||
for t in self.typeattributes():
|
||||
if t == name:
|
||||
return t
|
||||
|
||||
raise InvalidType("{0} is not a valid type attribute".format(name))
|
||||
|
||||
def lookup_user(self, name):
|
||||
"""Look up a user by name."""
|
||||
@ -572,19 +584,11 @@ cdef class SELinuxPolicy:
|
||||
|
||||
def types(self):
|
||||
"""Iterator over all types."""
|
||||
cdef qpol_iterator_t *iter
|
||||
if qpol_policy_get_type_iter(self.handle, &iter):
|
||||
raise MemoryError
|
||||
|
||||
return qpol_iterator_factory(self, iter, type_factory_iter, ValueError)
|
||||
return TypeHashtabIterator.factory(self, &self.handle.p.p.symtab[sepol.SYM_TYPES].table)
|
||||
|
||||
def typeattributes(self):
|
||||
"""Iterator over all (type) attributes."""
|
||||
cdef qpol_iterator_t *iter
|
||||
if qpol_policy_get_type_iter(self.handle, &iter):
|
||||
raise MemoryError
|
||||
|
||||
return qpol_iterator_factory(self, iter, attribute_factory_iter, ValueError)
|
||||
return TypeAttributeHashtabIterator.factory(self, &self.handle.p.p.symtab[sepol.SYM_TYPES].table)
|
||||
|
||||
def users(self):
|
||||
"""Iterator which yields all roles."""
|
||||
|
@ -406,8 +406,12 @@ cdef extern from "<sepol/policydb/policydb.h>":
|
||||
#
|
||||
# type_set_t
|
||||
#
|
||||
cdef int TYPE_TYPE
|
||||
cdef int TYPE_ATTRIB
|
||||
cdef int TYPE_ALIAS
|
||||
cdef int TYPE_STAR
|
||||
cdef int TYPE_COMP
|
||||
cdef int TYPE_FLAGS_PERMISSIVE
|
||||
|
||||
cdef struct type_set:
|
||||
ebitmap_t types
|
||||
|
@ -240,7 +240,7 @@ cdef class AVRule(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, <sepol.type_datum_t *> t)
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
@ -252,7 +252,7 @@ cdef class AVRule(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, <sepol.type_datum_t *> t)
|
||||
|
||||
@property
|
||||
def tclass(self):
|
||||
@ -526,7 +526,7 @@ cdef class TERule(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, <sepol.type_datum_t *>t)
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
@ -538,7 +538,7 @@ cdef class TERule(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, <sepol.type_datum_t *>t)
|
||||
|
||||
@property
|
||||
def tclass(self):
|
||||
@ -560,7 +560,7 @@ cdef class TERule(PolicyRule):
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_factory(self.policy, t, False)
|
||||
return Type.factory(self.policy, <sepol.type_datum_t *>t)
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
@ -691,26 +691,12 @@ cdef class FileNameTERule(PolicyRule):
|
||||
@property
|
||||
def source(self):
|
||||
"""The rule's source type/attribute."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_filename_trans_get_source_type(self.policy.handle, self.handle, &t):
|
||||
ex = LowLevelPolicyError("Error reading source type/attr for TE rule: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, self.policy.handle.p.p.type_val_to_struct[self.handle.stype - 1])
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
"""The rule's target type/attribute."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_filename_trans_get_target_type(self.policy.handle, self.handle, &t):
|
||||
ex = LowLevelPolicyError("Error reading target type/attr for TE rule: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return type_or_attr_factory(self.policy, t)
|
||||
return type_or_attr_factory(self.policy, self.policy.handle.p.p.type_val_to_struct[self.handle.ttype - 1])
|
||||
|
||||
@property
|
||||
def tclass(self):
|
||||
@ -725,14 +711,15 @@ cdef class FileNameTERule(PolicyRule):
|
||||
@property
|
||||
def default(self):
|
||||
"""The rule's default type."""
|
||||
cdef const qpol_type_t *t
|
||||
if qpol_filename_trans_get_default_type(self.policy.handle, self.handle, &t):
|
||||
ex = LowLevelPolicyError("Error reading default type for TE rule: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
cdef sepol.filename_trans_datum_t *datum
|
||||
datum = <sepol.filename_trans_datum_t *> hashtab_search(
|
||||
self.policy.handle.p.p.filename_trans, <sepol.hashtab_key_t> self.handle)
|
||||
|
||||
return type_factory(self.policy, t, False)
|
||||
if datum == NULL:
|
||||
raise LowLevelPolicyError("Error reading default type for TE rule.")
|
||||
|
||||
return Type.factory(self.policy,
|
||||
<sepol.type_datum_t *> self.policy.handle.p.p.type_val_to_struct[datum.otype - 1])
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
|
@ -17,157 +17,26 @@
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import warnings
|
||||
|
||||
#
|
||||
# Type factory functions
|
||||
# Cache objects
|
||||
#
|
||||
cdef dict _type_cache = {}
|
||||
|
||||
cdef inline Type type_factory_lookup(SELinuxPolicy policy, str name, deref):
|
||||
"""Factory function variant for constructing Type objects by name."""
|
||||
|
||||
cdef const qpol_type_t *symbol
|
||||
|
||||
if qpol_policy_get_type_by_name(policy.handle, name.encode(), &symbol):
|
||||
raise InvalidType("{0} is not a valid type".format(name))
|
||||
|
||||
return type_factory(policy, symbol, deref)
|
||||
|
||||
|
||||
cdef inline Type type_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol):
|
||||
"""Factory function variant for iterating over Type objects."""
|
||||
return type_factory(policy, <const qpol_type_t *> symbol.obj, False)
|
||||
|
||||
|
||||
cdef inline Type type_factory(SELinuxPolicy policy, const qpol_type_t *symbol, deref):
|
||||
"""Factory function for creating Type objects."""
|
||||
cdef unsigned char isattr
|
||||
cdef unsigned char isalias
|
||||
cdef const char *name
|
||||
|
||||
if qpol_type_get_isattr(policy.handle, symbol, &isattr):
|
||||
ex = LowLevelPolicyError("Error determining if type is an attribute: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
if isattr:
|
||||
if qpol_type_get_name(policy.handle, symbol, &name):
|
||||
raise ValueError("The specified type is an attribute.")
|
||||
|
||||
raise ValueError("{0} is an attribute".format(name))
|
||||
|
||||
if qpol_type_get_isalias(policy.handle, symbol, &isalias):
|
||||
ex = LowLevelPolicyError("Error determining if type is an alias: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
if isalias and not deref:
|
||||
if qpol_type_get_name(policy.handle, symbol, &name):
|
||||
raise ValueError("The specified type is an alias.")
|
||||
|
||||
raise ValueError("{0} is an alias".format(name))
|
||||
|
||||
try:
|
||||
return _type_cache[<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
t = Type()
|
||||
t.policy = policy
|
||||
t.handle = symbol
|
||||
_type_cache[<uintptr_t>symbol] = t
|
||||
return t
|
||||
|
||||
#
|
||||
# Attribute factory functions
|
||||
#
|
||||
cdef dict _typeattr_cache = {}
|
||||
|
||||
cdef inline TypeAttribute attribute_factory_lookup(SELinuxPolicy policy, str name):
|
||||
"""Factory function variant for constructing TypeAttribute objects by name."""
|
||||
|
||||
cdef const qpol_type_t *symbol
|
||||
if qpol_policy_get_type_by_name(policy.handle, name.encode(), &symbol):
|
||||
raise InvalidType("{0} is not a valid attribute".format(name))
|
||||
|
||||
return attribute_factory(policy, symbol)
|
||||
|
||||
|
||||
cdef inline TypeAttribute attribute_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol):
|
||||
"""Factory function variant for iterating over TypeAttribute objects."""
|
||||
return attribute_factory(policy, <const qpol_type_t *> symbol.obj)
|
||||
|
||||
|
||||
cdef inline TypeAttribute attribute_factory(SELinuxPolicy policy, const qpol_type_t *symbol):
|
||||
"""Factory function for creating TypeAttribute objects."""
|
||||
|
||||
cdef unsigned char isattr
|
||||
cdef const char *name
|
||||
|
||||
if qpol_type_get_isattr(policy.handle, symbol, &isattr):
|
||||
ex = LowLevelPolicyError("Error determining if type is an attribute: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
if not isattr:
|
||||
if qpol_type_get_name(policy.handle, symbol, &name):
|
||||
raise ValueError("The symbol is a type.")
|
||||
|
||||
raise ValueError("{0} is a type".format(name))
|
||||
|
||||
try:
|
||||
return _typeattr_cache[<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
a = TypeAttribute()
|
||||
a.policy = policy
|
||||
a.handle = symbol
|
||||
_typeattr_cache[<uintptr_t>symbol] = a
|
||||
return a
|
||||
|
||||
#
|
||||
# Type or Attribute factory functions
|
||||
# Type or attribute factory function
|
||||
#
|
||||
cdef inline BaseType type_or_attr_factory_lookup(SELinuxPolicy policy, str name, deref):
|
||||
"""Factory function variant for constructing Type objects by name."""
|
||||
|
||||
cdef const qpol_type_t *symbol
|
||||
cdef unsigned char isalias
|
||||
|
||||
if qpol_policy_get_type_by_name(policy.handle, name.encode(), &symbol):
|
||||
raise InvalidType("{0} is not a valid type or type attribute".format(name))
|
||||
|
||||
if qpol_type_get_isalias(policy.handle, symbol, &isalias):
|
||||
ex = LowLevelPolicyError("Error determining if type is an alias: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
if isalias and not deref:
|
||||
raise ValueError("{0} is an alias.".format(name))
|
||||
|
||||
return type_or_attr_factory(policy, symbol)
|
||||
|
||||
|
||||
cdef inline BaseType type_or_attr_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol):
|
||||
"""Factory function variant for iterating over Type or TypeAttribute objects."""
|
||||
return type_or_attr_factory(policy, <const qpol_type_t *> symbol.obj)
|
||||
|
||||
|
||||
cdef inline BaseType type_or_attr_factory(SELinuxPolicy policy, const qpol_type_t *symbol):
|
||||
cdef type_or_attr_factory(SELinuxPolicy policy, sepol.type_datum_t *symbol):
|
||||
"""Factory function for creating type or attribute objects."""
|
||||
cdef sepol.type_datum_t *handle
|
||||
|
||||
cdef unsigned char i
|
||||
if qpol_type_get_isattr(policy.handle, symbol, &i):
|
||||
ex = LowLevelPolicyError("Error determining if type is an attribute: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
if i:
|
||||
return attribute_factory(policy, symbol)
|
||||
if symbol.flavor == sepol.TYPE_ATTRIB:
|
||||
return TypeAttribute.factory(policy, symbol)
|
||||
else:
|
||||
return type_factory(policy, symbol, False)
|
||||
return Type.factory(policy, symbol)
|
||||
|
||||
|
||||
#
|
||||
@ -177,17 +46,10 @@ cdef class BaseType(PolicySymbol):
|
||||
|
||||
"""Type/attribute base class."""
|
||||
|
||||
cdef const qpol_type_t *handle
|
||||
cdef sepol.type_datum_t *handle
|
||||
|
||||
def __str__(self):
|
||||
cdef const char *name
|
||||
|
||||
if qpol_type_get_name(self.policy.handle, self.handle, &name):
|
||||
ex = LowLevelPolicyError("Error reading type name: {}".format(strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return intern(name)
|
||||
return intern(self.policy.handle.p.p.sym_val_to_name[sepol.SYM_TYPES][self.handle.s.value - 1])
|
||||
|
||||
def _eq(self, BaseType other):
|
||||
"""Low-level equality check (C pointers)."""
|
||||
@ -214,9 +76,25 @@ cdef class Type(BaseType):
|
||||
|
||||
"""A type."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.type_datum_t *symbol):
|
||||
"""Factory function for creating Type objects."""
|
||||
if symbol.flavor != sepol.TYPE_TYPE:
|
||||
raise ValueError("{0} is not a type".format(
|
||||
policy.handle.p.p.sym_val_to_name[sepol.SYM_TYPES][symbol.s.value - 1]))
|
||||
|
||||
try:
|
||||
return _type_cache[<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
t = Type()
|
||||
t.policy = policy
|
||||
t.handle = symbol
|
||||
_type_cache[<uintptr_t>symbol] = t
|
||||
return t
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# shallow copy as all of the members are immutable
|
||||
newobj = type_factory(self.policy, self.handle, False)
|
||||
newobj = Type.factory(self.policy, self.handle)
|
||||
memo[id(self)] = newobj
|
||||
return newobj
|
||||
|
||||
@ -231,19 +109,12 @@ cdef class Type(BaseType):
|
||||
return <bytes>(<char *>self.handle)
|
||||
|
||||
cdef _unpickle(self, bytes handle):
|
||||
memcpy(&self.handle, <char *>handle, sizeof(qpol_type_t*))
|
||||
memcpy(&self.handle, <char *>handle, sizeof(sepol.type_datum_t*))
|
||||
|
||||
@property
|
||||
def ispermissive(self):
|
||||
"""(T/F) the type is permissive."""
|
||||
cdef unsigned char i
|
||||
if qpol_type_get_ispermissive(self.policy.handle, self.handle, &i):
|
||||
ex = LowLevelPolicyError("Error determining if type is permissive: {}".format(
|
||||
strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return bool(i)
|
||||
return <bint> ebitmap_get_bit(&self.policy.handle.p.p.permissive_map, self.handle.s.value)
|
||||
|
||||
def expand(self):
|
||||
"""Generator that expands this into its member types."""
|
||||
@ -251,21 +122,11 @@ cdef class Type(BaseType):
|
||||
|
||||
def attributes(self):
|
||||
"""Generator that yields all attributes for this type."""
|
||||
cdef qpol_iterator_t *iter
|
||||
if qpol_type_get_attr_iter(self.policy.handle, self.handle, &iter) < 0:
|
||||
ex = LowLevelPolicyError("Error reading type attributes: {}".format(strerror(errno)))
|
||||
ex.errno = errno
|
||||
raise ex
|
||||
|
||||
return qpol_iterator_factory(self.policy, iter, attribute_factory_iter)
|
||||
return TypeAttributeEbitmapIterator.factory(self.policy, &self.handle.types)
|
||||
|
||||
def aliases(self):
|
||||
"""Generator that yields all aliases for this type."""
|
||||
cdef qpol_iterator_t *iter
|
||||
if qpol_type_get_alias_iter(self.policy.handle, self.handle, &iter):
|
||||
raise MemoryError
|
||||
|
||||
return qpol_iterator_factory(self.policy, iter, string_factory_iter)
|
||||
return TypeAliasHashtabIterator.factory(self.policy, &self.policy.handle.p.p.symtab[sepol.SYM_TYPES].table, self)
|
||||
|
||||
def statement(self):
|
||||
attrs = list(self.attributes())
|
||||
@ -286,6 +147,22 @@ cdef class TypeAttribute(BaseType):
|
||||
|
||||
"""A type attribute."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.type_datum_t *symbol):
|
||||
"""Factory function for creating TypeAttribute objects."""
|
||||
if symbol.flavor != sepol.TYPE_ATTRIB:
|
||||
raise ValueError("{0} is not an attribute".format(
|
||||
policy.handle.p.p.sym_val_to_name[sepol.SYM_TYPES][symbol.s.value - 1]))
|
||||
|
||||
try:
|
||||
return _typeattr_cache[<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
t = TypeAttribute()
|
||||
t.policy = policy
|
||||
t.handle = symbol
|
||||
_typeattr_cache[<uintptr_t>symbol] = t
|
||||
return t
|
||||
|
||||
def __contains__(self, other):
|
||||
for type_ in self.expand():
|
||||
if other == type_:
|
||||
@ -295,11 +172,7 @@ cdef class TypeAttribute(BaseType):
|
||||
|
||||
def expand(self):
|
||||
"""Generator that expands this attribute into its member types."""
|
||||
cdef qpol_iterator_t *iter
|
||||
if qpol_type_get_type_iter(self.policy.handle, self.handle, &iter) < 0:
|
||||
raise MemoryError
|
||||
|
||||
return qpol_iterator_factory(self.policy, iter, type_factory_iter)
|
||||
return TypeEbitmapIterator.factory(self.policy, &self.handle.types)
|
||||
|
||||
def attributes(self):
|
||||
"""Generator that yields all attributes for this type."""
|
||||
@ -316,3 +189,230 @@ cdef class TypeAttribute(BaseType):
|
||||
|
||||
def statement(self):
|
||||
return "attribute {0};".format(self)
|
||||
|
||||
|
||||
#
|
||||
# Hash Table Iterator Classes
|
||||
#
|
||||
cdef inline type_is_alias(sepol.type_datum_t *datum):
|
||||
"""Determine if the type datum is an alias."""
|
||||
return (datum.primary == 0 and datum.flavor == sepol.TYPE_TYPE) \
|
||||
or datum.flavor == sepol.TYPE_ALIAS
|
||||
|
||||
|
||||
cdef class TypeHashtabIterator(HashtabIterator):
|
||||
|
||||
"""Iterate over types in the policy."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table):
|
||||
"""Factory function for creating Role iterators."""
|
||||
i = TypeHashtabIterator()
|
||||
i.policy = policy
|
||||
i.table = table
|
||||
i.reset()
|
||||
return i
|
||||
|
||||
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 type_is_alias(datum):
|
||||
super().__next__()
|
||||
datum = <sepol.type_datum_t *> self.curr.datum
|
||||
|
||||
return 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 not type_is_alias(datum):
|
||||
count += 1
|
||||
|
||||
node = node.next
|
||||
|
||||
bucket += 1
|
||||
|
||||
return count
|
||||
|
||||
def reset(self):
|
||||
super().reset()
|
||||
|
||||
# advance over any attributes or aliases
|
||||
while (<sepol.type_datum_t *> self.node.datum).flavor != sepol.TYPE_TYPE:
|
||||
self._next_node()
|
||||
|
||||
|
||||
cdef class TypeAttributeHashtabIterator(HashtabIterator):
|
||||
|
||||
"""Iterate over type attributes in the policy."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table):
|
||||
"""Factory function for creating Role iterators."""
|
||||
i = TypeAttributeHashtabIterator()
|
||||
i.policy = policy
|
||||
i.table = table
|
||||
i.reset()
|
||||
return i
|
||||
|
||||
def __next__(self):
|
||||
super().__next__()
|
||||
while (<sepol.type_datum_t *> self.curr.datum).flavor != sepol.TYPE_ATTRIB:
|
||||
super().__next__()
|
||||
|
||||
return TypeAttribute.factory(self.policy, <sepol.type_datum_t *> self.curr.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_ATTRIB:
|
||||
count += 1
|
||||
|
||||
node = node.next
|
||||
|
||||
bucket += 1
|
||||
|
||||
return count
|
||||
|
||||
def reset(self):
|
||||
super().reset()
|
||||
|
||||
# advance over any attributes or aliases
|
||||
while (<sepol.type_datum_t *> self.node.datum).flavor != sepol.TYPE_ATTRIB:
|
||||
self._next_node()
|
||||
|
||||
|
||||
cdef class TypeAliasHashtabIterator(HashtabIterator):
|
||||
|
||||
"""Iterate over type aliases in the policy."""
|
||||
|
||||
cdef uint32_t primary
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table, Type primary):
|
||||
"""Factory function for creating type alias iterators."""
|
||||
i = TypeAliasHashtabIterator()
|
||||
i.policy = policy
|
||||
i.table = table
|
||||
i.primary = primary.handle.s.value
|
||||
i.reset()
|
||||
return i
|
||||
|
||||
def __next__(self):
|
||||
super().__next__()
|
||||
datum = <sepol.type_datum_t *> self.curr.datum if self.curr else NULL
|
||||
|
||||
while datum != NULL and (not type_is_alias(datum) or datum.s.value != self.primary):
|
||||
super().__next__()
|
||||
datum = <sepol.type_datum_t *> self.curr.datum if self.curr else NULL
|
||||
|
||||
return intern(self.curr.key)
|
||||
|
||||
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 self.primary == datum.s.value and type_is_alias(datum):
|
||||
count += 1
|
||||
|
||||
node = node.next
|
||||
|
||||
bucket += 1
|
||||
|
||||
return count
|
||||
|
||||
def reset(self):
|
||||
super().reset()
|
||||
|
||||
cdef sepol.type_datum_t *datum = <sepol.type_datum_t *> self.node.datum if self.node else NULL
|
||||
|
||||
# advance over any attributes or aliases
|
||||
while datum != NULL and (not type_is_alias(datum) and self.primary != datum.s.value):
|
||||
self._next_node()
|
||||
|
||||
if self.node == NULL or self.bucket >= self.table[0].size:
|
||||
break
|
||||
|
||||
datum = <sepol.type_datum_t *> self.node.datum if self.node else NULL
|
||||
|
||||
|
||||
#
|
||||
# Ebitmap Iterator Classes
|
||||
#
|
||||
cdef class TypeEbitmapIterator(EbitmapIterator):
|
||||
|
||||
"""Iterate over a type ebitmap."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.ebitmap_t *symbol):
|
||||
"""Factory function for creating TypeEbitmapIterator."""
|
||||
i = TypeEbitmapIterator()
|
||||
i.policy = policy
|
||||
i.bmap = symbol
|
||||
i.reset()
|
||||
return i
|
||||
|
||||
@staticmethod
|
||||
cdef factory_from_set(SELinuxPolicy policy, sepol.type_set_t *symbol):
|
||||
"""Factory function for creating TypeEbitmapIterator from a type set."""
|
||||
if symbol.flags:
|
||||
warnings.warn("* or ~ in the type set; this is not implemented in SETools.")
|
||||
if symbol.negset.node != NULL:
|
||||
warnings.warn("Negations in the type set; this is not implemented in SETools.")
|
||||
|
||||
return TypeEbitmapIterator.factory(policy, &symbol.types)
|
||||
|
||||
def __next__(self):
|
||||
super().__next__()
|
||||
return Type.factory(self.policy, self.policy.handle.p.p.type_val_to_struct[self.bit])
|
||||
|
||||
|
||||
cdef class TypeAttributeEbitmapIterator(EbitmapIterator):
|
||||
|
||||
"""Iterate over a type attribute ebitmap."""
|
||||
|
||||
@staticmethod
|
||||
cdef factory(SELinuxPolicy policy, sepol.ebitmap_t *bmap):
|
||||
"""Factory function for creating TypeAttributeEbitmapIterator."""
|
||||
i = TypeAttributeEbitmapIterator()
|
||||
i.policy = policy
|
||||
i.bmap = bmap
|
||||
i.reset()
|
||||
return i
|
||||
|
||||
@staticmethod
|
||||
cdef factory_from_set(SELinuxPolicy policy, sepol.type_set_t *symbol):
|
||||
"""Factory function for creating TypeAttributeEbitmapIterator from a type set."""
|
||||
if symbol.flags:
|
||||
warnings.warn("* or ~ in the type set; this is not implemented in SETools.")
|
||||
if symbol.negset.node != NULL:
|
||||
warnings.warn("Negations in the type set; this is not implemented in SETools.")
|
||||
|
||||
return TypeAttributeEbitmapIterator.factory(policy, &symbol.types)
|
||||
|
||||
def __next__(self):
|
||||
super().__next__()
|
||||
return TypeAttribute.factory(self.policy,
|
||||
self.policy.handle.p.p.type_val_to_struct[self.bit])
|
||||
|
2
setup.py
2
setup.py
@ -76,13 +76,11 @@ ext_py_mods = [Extension('setools.policyrep.libpolicyrep',
|
||||
'libqpol/ftrule_query.c',
|
||||
'libqpol/iterator.c',
|
||||
'libqpol/mlsrule_query.c',
|
||||
'libqpol/permissive_query.c',
|
||||
'libqpol/policy.c',
|
||||
'libqpol/policy_extend.c',
|
||||
'libqpol/rbacrule_query.c',
|
||||
'libqpol/role_query.c',
|
||||
'libqpol/terule_query.c',
|
||||
'libqpol/type_query.c',
|
||||
'libqpol/user_query.c'],
|
||||
include_dirs=include_dirs,
|
||||
extra_compile_args=['-Werror', '-Wextra',
|
||||
|
Loading…
Reference in New Issue
Block a user