class-perm-query.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  *
00004  * Provides a way for setools to make queries about classes, commons,
00005  * and permissions within a policy.  The caller obtains a query
00006  * object, fills in its parameters, and then runs the query; it
00007  * obtains a vector of results.  Searches are conjunctive -- all
00008  * fields of the search query must match for a datum to be added to
00009  * the results query.
00010  *
00011  * @author Jeremy A. Mowery jmowery@tresys.com
00012  * @author Jason Tang  jtang@tresys.com
00013  *
00014  * Copyright (C) 2006-2007 Tresys Technology, LLC
00015  *
00016  *  This library is free software; you can redistribute it and/or
00017  *  modify it under the terms of the GNU Lesser General Public
00018  *  License as published by the Free Software Foundation; either
00019  *  version 2.1 of the License, or (at your option) any later version.
00020  *
00021  *  This library is distributed in the hope that it will be useful,
00022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  *  Lesser General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU Lesser General Public
00027  *  License along with this library; if not, write to the Free Software
00028  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00029  */
00030 
00031 #include "policy-query-internal.h"
00032 #include <errno.h>
00033 #include <string.h>
00034 
00035 struct apol_class_query
00036 {
00037         char *class_name, *common_name;
00038         unsigned int flags;
00039         regex_t *class_regex, *common_regex;
00040 };
00041 
00042 struct apol_common_query
00043 {
00044         char *common_name;
00045         unsigned int flags;
00046         regex_t *regex;
00047 };
00048 
00049 struct apol_perm_query
00050 {
00051         char *perm_name;
00052         unsigned int flags;
00053         regex_t *regex;
00054 };
00055 
00056 /******************** class queries ********************/
00057 
00058 int apol_class_get_by_query(const apol_policy_t * p, apol_class_query_t * c, apol_vector_t ** v)
00059 {
00060         qpol_iterator_t *iter = NULL, *perm_iter = NULL;
00061         int retval = -1, append_class;
00062         *v = NULL;
00063         if (qpol_policy_get_class_iter(p->p, &iter) < 0) {
00064                 return -1;
00065         }
00066         if ((*v = apol_vector_create(NULL)) == NULL) {
00067                 ERR(p, "%s", strerror(errno));
00068                 goto cleanup;
00069         }
00070         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00071                 qpol_class_t *class_datum;
00072                 if (qpol_iterator_get_item(iter, (void **)&class_datum) < 0) {
00073                         goto cleanup;
00074                 }
00075                 append_class = 1;
00076                 if (c != NULL) {
00077                         const char *class_name, *common_name = NULL;
00078                         const qpol_common_t *common_datum;
00079                         int compval;
00080                         if (qpol_class_get_name(p->p, class_datum, &class_name) < 0) {
00081                                 goto cleanup;
00082                         }
00083                         compval = apol_compare(p, class_name, c->class_name, c->flags, &(c->class_regex));
00084                         if (compval < 0) {
00085                                 goto cleanup;
00086                         } else if (compval == 0) {
00087                                 continue;
00088                         }
00089                         if (qpol_class_get_common(p->p, class_datum, &common_datum) < 0) {
00090                                 goto cleanup;
00091                         }
00092                         if (common_datum == NULL) {
00093                                 if (c->common_name != NULL && c->common_name[0] != '\0') {
00094                                         continue;
00095                                 }
00096                         } else {
00097                                 if (qpol_common_get_name(p->p, common_datum, &common_name) < 0) {
00098                                         goto cleanup;
00099                                 }
00100                                 compval = apol_compare(p, common_name, c->common_name, c->flags, &(c->common_regex));
00101                                 if (compval < 0) {
00102                                         goto cleanup;
00103                                 } else if (compval == 0) {
00104                                         continue;
00105                                 }
00106                         }
00107                 }
00108                 if (append_class && apol_vector_append(*v, class_datum)) {
00109                         ERR(p, "%s", strerror(ENOMEM));
00110                         goto cleanup;
00111                 }
00112         }
00113 
00114         retval = 0;
00115       cleanup:
00116         if (retval != 0) {
00117                 apol_vector_destroy(v);
00118         }
00119         qpol_iterator_destroy(&iter);
00120         qpol_iterator_destroy(&perm_iter);
00121         return retval;
00122 }
00123 
00124 apol_class_query_t *apol_class_query_create(void)
00125 {
00126         return calloc(1, sizeof(apol_class_query_t));
00127 }
00128 
00129 void apol_class_query_destroy(apol_class_query_t ** c)
00130 {
00131         if (*c != NULL) {
00132                 free((*c)->class_name);
00133                 free((*c)->common_name);
00134                 apol_regex_destroy(&(*c)->class_regex);
00135                 apol_regex_destroy(&(*c)->common_regex);
00136                 free(*c);
00137                 *c = NULL;
00138         }
00139 }
00140 
00141 int apol_class_query_set_class(const apol_policy_t * p, apol_class_query_t * c, const char *name)
00142 {
00143         return apol_query_set(p, &c->class_name, &c->class_regex, name);
00144 }
00145 
00146 int apol_class_query_set_common(const apol_policy_t * p, apol_class_query_t * c, const char *name)
00147 {
00148         return apol_query_set(p, &c->common_name, &c->common_regex, name);
00149 }
00150 
00151 int apol_class_query_set_regex(const apol_policy_t * p, apol_class_query_t * c, int is_regex)
00152 {
00153         return apol_query_set_regex(p, &c->flags, is_regex);
00154 }
00155 
00156 /******************** common queries ********************/
00157 
00158 int apol_common_get_by_query(const apol_policy_t * p, apol_common_query_t * c, apol_vector_t ** v)
00159 {
00160         qpol_iterator_t *iter = NULL;
00161         int retval = -1;
00162         *v = NULL;
00163         if (qpol_policy_get_common_iter(p->p, &iter) < 0) {
00164                 return -1;
00165         }
00166         if ((*v = apol_vector_create(NULL)) == NULL) {
00167                 ERR(p, "%s", strerror(errno));
00168                 goto cleanup;
00169         }
00170         for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00171                 qpol_common_t *common_datum;
00172                 if (qpol_iterator_get_item(iter, (void **)&common_datum) < 0) {
00173                         goto cleanup;
00174                 }
00175                 if (c != NULL) {
00176                         const char *common_name = NULL;
00177                         int compval;
00178                         if (qpol_common_get_name(p->p, common_datum, &common_name) < 0) {
00179                                 goto cleanup;
00180                         }
00181                         compval = apol_compare(p, common_name, c->common_name, c->flags, &(c->regex));
00182                         if (compval < 0) {
00183                                 goto cleanup;
00184                         } else if (compval == 0) {
00185                                 continue;
00186                         }
00187                 }
00188                 if (apol_vector_append(*v, common_datum)) {
00189                         ERR(p, "%s", strerror(errno));
00190                         goto cleanup;
00191                 }
00192         }
00193 
00194         retval = 0;
00195       cleanup:
00196         if (retval != 0) {
00197                 apol_vector_destroy(v);
00198         }
00199         qpol_iterator_destroy(&iter);
00200         return retval;
00201 }
00202 
00203 apol_common_query_t *apol_common_query_create(void)
00204 {
00205         return calloc(1, sizeof(apol_common_query_t));
00206 }
00207 
00208 void apol_common_query_destroy(apol_common_query_t ** c)
00209 {
00210         if (*c != NULL) {
00211                 free((*c)->common_name);
00212                 apol_regex_destroy(&(*c)->regex);
00213                 free(*c);
00214                 *c = NULL;
00215         }
00216 }
00217 
00218 int apol_common_query_set_common(const apol_policy_t * p, apol_common_query_t * c, const char *name)
00219 {
00220         return apol_query_set(p, &c->common_name, &c->regex, name);
00221 }
00222 
00223 int apol_common_query_set_regex(const apol_policy_t * p, apol_common_query_t * c, int is_regex)
00224 {
00225         return apol_query_set_regex(p, &c->flags, is_regex);
00226 }
00227 
00228 /******************** permission queries ********************/
00229 
00230 int apol_perm_get_by_query(const apol_policy_t * p, apol_perm_query_t * pq, apol_vector_t ** v)
00231 {
00232         qpol_iterator_t *class_iter = NULL, *common_iter = NULL, *perm_iter = NULL;
00233         int retval = -1, compval;
00234         char *perm_name;
00235         *v = NULL;
00236         if (qpol_policy_get_class_iter(p->p, &class_iter) < 0 || qpol_policy_get_common_iter(p->p, &common_iter) < 0) {
00237                 goto cleanup;
00238         }
00239         if ((*v = apol_vector_create(NULL)) == NULL) {
00240                 ERR(p, "%s", strerror(errno));
00241                 goto cleanup;
00242         }
00243         for (; !qpol_iterator_end(class_iter); qpol_iterator_next(class_iter)) {
00244                 qpol_class_t *class_datum;
00245                 if (qpol_iterator_get_item(class_iter, (void **)&class_datum) < 0 ||
00246                     qpol_class_get_perm_iter(p->p, class_datum, &perm_iter) < 0) {
00247                         goto cleanup;
00248                 }
00249                 for (; !qpol_iterator_end(perm_iter); qpol_iterator_next(perm_iter)) {
00250                         if (qpol_iterator_get_item(perm_iter, (void **)&perm_name) < 0) {
00251                                 goto cleanup;
00252                         }
00253                         if (pq == NULL) {
00254                                 compval = 1;
00255                         } else {
00256                                 compval = apol_compare(p, perm_name, pq->perm_name, pq->flags, &(pq->regex));
00257                         }
00258                         if (compval < 0) {
00259                                 goto cleanup;
00260                         } else if (compval == 1 && apol_vector_append_unique(*v, perm_name, apol_str_strcmp, NULL) < 0) {
00261                                 ERR(p, "%s", strerror(ENOMEM));
00262                                 goto cleanup;
00263                         }
00264                 }
00265                 qpol_iterator_destroy(&perm_iter);
00266         }
00267 
00268         for (; !qpol_iterator_end(common_iter); qpol_iterator_next(common_iter)) {
00269                 qpol_common_t *common_datum;
00270                 if (qpol_iterator_get_item(common_iter, (void **)&common_datum) < 0 ||
00271                     qpol_common_get_perm_iter(p->p, common_datum, &perm_iter) < 0) {
00272                         goto cleanup;
00273                 }
00274                 for (; !qpol_iterator_end(perm_iter); qpol_iterator_next(perm_iter)) {
00275                         if (qpol_iterator_get_item(perm_iter, (void **)&perm_name) < 0) {
00276                                 goto cleanup;
00277                         }
00278                         if (pq == NULL) {
00279                                 compval = 1;
00280                         } else {
00281                                 compval = apol_compare(p, perm_name, pq->perm_name, pq->flags, &(pq->regex));
00282                         }
00283                         if (compval < 0) {
00284                                 goto cleanup;
00285                         } else if (compval == 1 && apol_vector_append_unique(*v, perm_name, apol_str_strcmp, NULL) < 0) {
00286                                 ERR(p, "%s", strerror(ENOMEM));
00287                                 goto cleanup;
00288                         }
00289                 }
00290                 qpol_iterator_destroy(&perm_iter);
00291         }
00292 
00293         retval = 0;
00294       cleanup:
00295         if (retval != 0) {
00296                 apol_vector_destroy(v);
00297         }
00298         qpol_iterator_destroy(&class_iter);
00299         qpol_iterator_destroy(&common_iter);
00300         qpol_iterator_destroy(&perm_iter);
00301         return retval;
00302 }
00303 
00304 apol_perm_query_t *apol_perm_query_create(void)
00305 {
00306         return calloc(1, sizeof(apol_perm_query_t));
00307 }
00308 
00309 void apol_perm_query_destroy(apol_perm_query_t ** pq)
00310 {
00311         if (*pq != NULL) {
00312                 free((*pq)->perm_name);
00313                 apol_regex_destroy(&(*pq)->regex);
00314                 free(*pq);
00315                 *pq = NULL;
00316         }
00317 }
00318 
00319 int apol_perm_query_set_perm(const apol_policy_t * p, apol_perm_query_t * pq, const char *name)
00320 {
00321         return apol_query_set(p, &pq->perm_name, &pq->regex, name);
00322 }
00323 
00324 int apol_perm_query_set_regex(const apol_policy_t * p, apol_perm_query_t * pq, int is_regex)
00325 {
00326         return apol_query_set_regex(p, &pq->flags, is_regex);
00327 }