role_query.c

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Implementation of the interface for searching and iterating over roles.
00004  *
00005  *  @author Kevin Carr kcarr@tresys.com
00006  *  @author Jeremy A. Mowery jmowery@tresys.com
00007  *  @author Jason Tang jtang@tresys.com
00008  *
00009  *  Copyright (C) 2006-2007 Tresys Technology, LLC
00010  *
00011  *  This library is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU Lesser General Public
00013  *  License as published by the Free Software Foundation; either
00014  *  version 2.1 of the License, or (at your option) any later version.
00015  *
00016  *  This library is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  Lesser General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU Lesser General Public
00022  *  License along with this library; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00024  */
00025 
00026 #include <stddef.h>
00027 #include <stdint.h>
00028 #include <stdlib.h>
00029 #include <qpol/iterator.h>
00030 #include <qpol/policy.h>
00031 #include <sepol/policydb/policydb.h>
00032 #include <sepol/policydb/expand.h>
00033 #include "iterator_internal.h"
00034 #include <qpol/role_query.h>
00035 #include <qpol/type_query.h>
00036 #include "qpol_internal.h"
00037 
00038 int qpol_policy_get_role_by_name(const qpol_policy_t * policy, const char *name, const qpol_role_t ** datum)
00039 {
00040         hashtab_datum_t internal_datum;
00041         policydb_t *db;
00042 
00043         if (policy == NULL || name == NULL || datum == NULL) {
00044                 if (datum != NULL)
00045                         *datum = NULL;
00046                 ERR(policy, "%s", strerror(EINVAL));
00047                 errno = EINVAL;
00048                 return STATUS_ERR;
00049         }
00050 
00051         db = &policy->p->p;
00052         internal_datum = hashtab_search(db->p_roles.table, (const hashtab_key_t)name);
00053         if (internal_datum == NULL) {
00054                 *datum = NULL;
00055                 ERR(policy, "could not find datum for role %s", name);
00056                 errno = ENOENT;
00057                 return STATUS_ERR;
00058         }
00059         *datum = (qpol_role_t *) internal_datum;
00060 
00061         return STATUS_SUCCESS;
00062 }
00063 
00064 int qpol_policy_get_role_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter)
00065 {
00066         policydb_t *db;
00067         int error = 0;
00068         hash_state_t *hs = NULL;
00069 
00070         if (policy == NULL || iter == NULL) {
00071                 if (iter != NULL)
00072                         *iter = NULL;
00073                 ERR(policy, "%s", strerror(EINVAL));
00074                 errno = EINVAL;
00075                 return STATUS_ERR;
00076         }
00077 
00078         db = &policy->p->p;
00079 
00080         hs = calloc(1, sizeof(hash_state_t));
00081         if (hs == NULL) {
00082                 error = errno;
00083                 ERR(policy, "%s", strerror(ENOMEM));
00084                 errno = error;
00085                 return STATUS_ERR;
00086         }
00087         hs->table = &db->p_roles.table;
00088         hs->node = (*(hs->table))->htable[0];
00089 
00090         if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur,
00091                                  hash_state_next, hash_state_end, hash_state_size, free, iter)) {
00092                 free(hs);
00093                 return STATUS_ERR;
00094         }
00095 
00096         if (hs->node == NULL)
00097                 hash_state_next(*iter);
00098 
00099         return STATUS_SUCCESS;
00100 }
00101 
00102 int qpol_role_get_value(const qpol_policy_t * policy, const qpol_role_t * datum, uint32_t * value)
00103 {
00104         role_datum_t *internal_datum = NULL;
00105 
00106         if (policy == NULL || datum == NULL || value == NULL) {
00107                 if (value != NULL)
00108                         *value = 0;
00109                 ERR(policy, "%s", strerror(EINVAL));
00110                 errno = EINVAL;
00111                 return STATUS_ERR;
00112         }
00113 
00114         internal_datum = (role_datum_t *) datum;
00115         *value = internal_datum->s.value;
00116 
00117         return STATUS_SUCCESS;
00118 }
00119 
00120 int qpol_role_get_dominate_iter(const qpol_policy_t * policy, const qpol_role_t * datum, qpol_iterator_t ** dominates)
00121 {
00122         role_datum_t *internal_datum = NULL;
00123         policydb_t *db = NULL;
00124         int error;
00125         ebitmap_state_t *es = NULL;
00126 
00127         if (policy == NULL || datum == NULL || dominates == NULL) {
00128                 if (dominates != NULL)
00129                         *dominates = NULL;
00130                 ERR(policy, "%s", strerror(EINVAL));
00131                 errno = EINVAL;
00132                 return STATUS_ERR;
00133         }
00134 
00135         internal_datum = (role_datum_t *) datum;
00136         db = &policy->p->p;
00137 
00138         if (!(es = calloc(1, sizeof(ebitmap_state_t)))) {
00139                 error = errno;
00140                 ERR(policy, "%s", "unable to create iterator state object");
00141                 errno = error;
00142                 return STATUS_ERR;
00143         }
00144         es->bmap = &internal_datum->dominates;
00145 
00146         if (qpol_iterator_create(policy, (void *)es, ebitmap_state_get_cur_role,
00147                                  ebitmap_state_next, ebitmap_state_end, ebitmap_state_size, free, dominates)) {
00148                 error = errno;
00149                 free(es);
00150                 errno = error;
00151                 return STATUS_ERR;
00152         }
00153 
00154         if (es->bmap->node && !ebitmap_get_bit(es->bmap, es->cur))
00155                 ebitmap_state_next(*dominates);
00156 
00157         return STATUS_SUCCESS;
00158 }
00159 
00160 int qpol_role_get_type_iter(const qpol_policy_t * policy, const qpol_role_t * datum, qpol_iterator_t ** types)
00161 {
00162         role_datum_t *internal_datum = NULL;
00163         policydb_t *db = NULL;
00164         ebitmap_t *expanded_set = NULL;
00165         int error;
00166         ebitmap_state_t *es = NULL;
00167 
00168         if (policy == NULL || datum == NULL || types == NULL) {
00169                 if (types != NULL)
00170                         *types = NULL;
00171                 ERR(policy, "%s", strerror(EINVAL));
00172                 errno = EINVAL;
00173                 return STATUS_ERR;
00174         }
00175 
00176         internal_datum = (role_datum_t *) datum;
00177         db = &policy->p->p;
00178 
00179         if (!(expanded_set = calloc(1, sizeof(ebitmap_t)))) {
00180                 error = errno;
00181                 ERR(policy, "%s", "unable to create bitmap");
00182                 errno = error;
00183                 return STATUS_ERR;
00184         }
00185 
00186         if (type_set_expand(&internal_datum->types, expanded_set, db, 1)) {
00187                 ebitmap_destroy(expanded_set);
00188                 free(expanded_set);
00189                 ERR(policy, "error reading type set for role %s", db->p_role_val_to_name[internal_datum->s.value - 1]);
00190                 errno = EIO;
00191                 return STATUS_ERR;
00192         }
00193 
00194         if (!(es = calloc(1, sizeof(ebitmap_state_t)))) {
00195                 error = errno;
00196                 ERR(policy, "%s", "unable to create iterator state object");
00197                 ebitmap_destroy(expanded_set);
00198                 free(expanded_set);
00199                 errno = error;
00200                 return STATUS_ERR;
00201         }
00202         es->bmap = expanded_set;
00203         es->cur = es->bmap->node ? es->bmap->node->startbit : 0;
00204 
00205         if (qpol_iterator_create(policy, (void *)es, ebitmap_state_get_cur_type,
00206                                  ebitmap_state_next, ebitmap_state_end, ebitmap_state_size, ebitmap_state_destroy, types)) {
00207                 error = errno;
00208                 ebitmap_state_destroy(es);
00209                 errno = error;
00210                 return STATUS_ERR;
00211         }
00212 
00213         if (es->bmap->node && !ebitmap_get_bit(es->bmap, es->cur))
00214                 ebitmap_state_next(*types);
00215 
00216         return STATUS_SUCCESS;
00217 }
00218 
00219 int qpol_role_get_name(const qpol_policy_t * policy, const qpol_role_t * datum, const char **name)
00220 {
00221         role_datum_t *internal_datum = NULL;
00222         policydb_t *db = NULL;
00223 
00224         if (policy == NULL || datum == NULL || name == NULL) {
00225                 if (name != NULL)
00226                         *name = NULL;
00227                 ERR(policy, "%s", strerror(EINVAL));
00228                 errno = EINVAL;
00229                 return STATUS_ERR;
00230         }
00231 
00232         db = &policy->p->p;
00233         internal_datum = (role_datum_t *) datum;
00234 
00235         *name = db->p_role_val_to_name[internal_datum->s.value - 1];
00236 
00237         return STATUS_SUCCESS;
00238 }