domain_and_file.c

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Implementation of the domain and file type module.
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) 2005-2007 Tresys Technology, LLC
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program 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
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00024  */
00025 
00026 #include "domain_and_file.h"
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 
00032 static const char *const mod_name = "domain_and_file";
00033 
00034 int domain_and_file_register(sechk_lib_t * lib)
00035 {
00036         sechk_module_t *mod = NULL;
00037         sechk_fn_t *fn_struct = NULL;
00038         sechk_name_value_t *nv = NULL;
00039 
00040         if (!lib) {
00041                 ERR(NULL, "%s", "No library");
00042                 errno = EINVAL;
00043                 return -1;
00044         }
00045 
00046         mod = sechk_lib_get_module(mod_name, lib);
00047         if (!mod) {
00048                 ERR(NULL, "%s", "Module unknown");
00049                 errno = EINVAL;
00050                 return -1;
00051         }
00052         mod->parent_lib = lib;
00053 
00054         /* assign descriptions */
00055         mod->brief_description = "types treated as a domain and file type";
00056         mod->detailed_description =
00057                 "--------------------------------------------------------------------------------\n"
00058                 "This module finds all types in the policy treated as both a domain and a file   \n"
00059                 "type.  See find_domains and find_file_types modules for details about the       \n"
00060                 "heuristics used to determine these types.  It is considered bad security\n"
00061                 "practice to use the same type for a domain and its data objects because it \n"
00062                 "requires that less restrictive access be granted to these types.\n";
00063         mod->opt_description = "Module requirements:\n" "   attribute names\n"
00064                 "   file_contexts\n"
00065                 "Module dependencies:\n" "   find_domains module\n" "   find_file_types module\n" "Module options:\n" "   none\n";
00066         mod->severity = SECHK_SEV_LOW;
00067         /* assign requirements */
00068         nv = sechk_name_value_new(SECHK_REQ_POLICY_CAP, SECHK_REQ_CAP_ATTRIB_NAMES);
00069         apol_vector_append(mod->requirements, (void *)nv);
00070         nv = sechk_name_value_new(SECHK_REQ_FILE_CONTEXTS, NULL);
00071         apol_vector_append(mod->requirements, (void *)nv);
00072 
00073         /* assign dependencies */
00074         apol_vector_append(mod->dependencies, sechk_name_value_new("module", "find_domains"));
00075         apol_vector_append(mod->dependencies, sechk_name_value_new("module", "find_file_types"));
00076 
00077         /* register functions */
00078         fn_struct = sechk_fn_new();
00079         if (!fn_struct) {
00080                 ERR(NULL, "%s", strerror(ENOMEM));
00081                 errno = ENOMEM;
00082                 return -1;
00083         }
00084         fn_struct->name = strdup(SECHK_MOD_FN_INIT);
00085         if (!fn_struct->name) {
00086                 ERR(NULL, "%s", strerror(ENOMEM));
00087                 errno = ENOMEM;
00088                 return -1;
00089         }
00090         fn_struct->fn = &domain_and_file_init;
00091         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00092                 ERR(NULL, "%s", strerror(ENOMEM));
00093                 errno = ENOMEM;
00094                 return -1;
00095         }
00096 
00097         fn_struct = sechk_fn_new();
00098         if (!fn_struct) {
00099                 ERR(NULL, "%s", strerror(ENOMEM));
00100                 errno = ENOMEM;
00101                 return -1;
00102         }
00103         fn_struct->name = strdup(SECHK_MOD_FN_RUN);
00104         if (!fn_struct->name) {
00105                 ERR(NULL, "%s", strerror(ENOMEM));
00106                 errno = ENOMEM;
00107                 return -1;
00108         }
00109         fn_struct->fn = domain_and_file_run;
00110         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00111                 ERR(NULL, "%s", strerror(ENOMEM));
00112                 errno = ENOMEM;
00113                 return -1;
00114         }
00115 
00116         mod->data_free = NULL;
00117 
00118         fn_struct = sechk_fn_new();
00119         if (!fn_struct) {
00120                 ERR(NULL, "%s", strerror(ENOMEM));
00121                 errno = ENOMEM;
00122                 return -1;
00123         }
00124         fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
00125         if (!fn_struct->name) {
00126                 ERR(NULL, "%s", strerror(ENOMEM));
00127                 errno = ENOMEM;
00128                 return -1;
00129         }
00130         fn_struct->fn = domain_and_file_print;
00131         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00132                 ERR(NULL, "%s", strerror(ENOMEM));
00133                 errno = ENOMEM;
00134                 return -1;
00135         }
00136 
00137         return 0;
00138 }
00139 
00140 int domain_and_file_init(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00141 {
00142         if (!mod || !policy) {
00143                 ERR(policy, "%s", "Invalid parameters");
00144                 errno = EINVAL;
00145                 return -1;
00146         }
00147         if (strcmp(mod_name, mod->name)) {
00148                 ERR(policy, "Wrong module (%s)", mod->name);
00149                 errno = EINVAL;
00150                 return -1;
00151         }
00152 
00153         mod->data = NULL;
00154 
00155         return 0;
00156 }
00157 
00158 int domain_and_file_run(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00159 {
00160         sechk_result_t *res = NULL;
00161         sechk_item_t *item = NULL;
00162         sechk_proof_t *proof = NULL;
00163         sechk_result_t *domain_res = NULL, *file_type_res = NULL;
00164         size_t i, j, k;
00165         sechk_mod_fn_t run_fn = NULL;
00166         sechk_name_value_t *dep = NULL;
00167         apol_vector_t *domain_vector;
00168         apol_vector_t *type_vector;
00169         qpol_policy_t *q = apol_policy_get_qpol(policy);
00170         int error = 0;
00171 
00172         if (!mod || !policy) {
00173                 ERR(policy, "%s", "Invalid parameters");
00174                 errno = EINVAL;
00175                 return -1;
00176         }
00177         if (strcmp(mod_name, mod->name)) {
00178                 ERR(policy, "Wrong module (%s)", mod->name);
00179                 errno = EINVAL;
00180                 return -1;
00181         }
00182 
00183         /* if already run return */
00184         if (mod->result)
00185                 return 0;
00186 
00187         res = sechk_result_new();
00188         if (!res) {
00189                 ERR(policy, "%s", strerror(ENOMEM));
00190                 errno = ENOMEM;
00191                 return -1;
00192         }
00193         res->test_name = strdup(mod_name);
00194         if (!res->test_name) {
00195                 error = errno;
00196                 ERR(policy, "%s", strerror(ENOMEM));
00197                 goto domain_and_file_run_fail;
00198         }
00199         res->item_type = SECHK_ITEM_TYPE;
00200         if (!(res->items = apol_vector_create(sechk_item_free))) {
00201                 error = errno;
00202                 ERR(policy, "%s", strerror(ENOMEM));
00203                 goto domain_and_file_run_fail;
00204         }
00205 
00206         /* run dependencies */
00207         for (i = 0; i < apol_vector_get_size(mod->dependencies); i++) {
00208                 dep = apol_vector_get_element(mod->dependencies, i);
00209                 run_fn = sechk_lib_get_module_function(dep->value, SECHK_MOD_FN_RUN, mod->parent_lib);
00210                 run_fn(sechk_lib_get_module(dep->value, mod->parent_lib), policy, NULL);
00211         }
00212 
00213         /* get results */
00214         domain_res = sechk_lib_get_module_result("find_domains", mod->parent_lib);
00215         if (!domain_res) {
00216                 error = errno;
00217                 ERR(policy, "%s", "Unable to get results for module find_domains");
00218                 goto domain_and_file_run_fail;
00219         }
00220         file_type_res = sechk_lib_get_module_result("find_file_types", mod->parent_lib);
00221         if (!file_type_res) {
00222                 error = errno;
00223                 ERR(policy, "%s", "Unable to get results for module find_file_types");
00224                 goto domain_and_file_run_fail;
00225         }
00226 
00227         /* get lists */
00228         domain_vector = (apol_vector_t *) domain_res->items;
00229         type_vector = (apol_vector_t *) file_type_res->items;
00230 
00231         /* build the both list */
00232         for (i = 0; i < apol_vector_get_size(type_vector); i++) {
00233                 sechk_item_t *type_item;
00234                 qpol_type_t *type;
00235                 const char *type_name;
00236 
00237                 type_item = apol_vector_get_element(type_vector, i);
00238                 type = type_item->item;
00239                 qpol_type_get_name(q, type, &type_name);
00240                 for (j = 0; j < apol_vector_get_size(domain_vector); j++) {
00241                         sechk_item_t *domain_item;
00242                         qpol_type_t *domain;
00243                         const char *domain_name;
00244 
00245                         domain_item = apol_vector_get_element(domain_vector, j);
00246                         domain = domain_item->item;
00247                         qpol_type_get_name(q, domain, &domain_name);
00248                         if (!strcmp(domain_name, type_name)) {
00249                                 item = sechk_item_new(NULL);
00250                                 if (!item) {
00251                                         error = errno;
00252                                         ERR(policy, "%s", strerror(ENOMEM));
00253                                         goto domain_and_file_run_fail;
00254                                 }
00255                                 item->item = (void *)domain;
00256                                 if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00257                                         error = errno;
00258                                         ERR(policy, "%s", strerror(ENOMEM));
00259                                         goto domain_and_file_run_fail;
00260                                 }
00261                                 for (k = 0; k < apol_vector_get_size(domain_item->proof); k++) {
00262                                         sechk_proof_t *domain_proof;
00263 
00264                                         domain_proof = apol_vector_get_element(domain_item->proof, k);
00265                                         proof = sechk_proof_new(NULL);
00266                                         if (!proof) {
00267                                                 error = errno;
00268                                                 ERR(policy, "%s", strerror(ENOMEM));
00269                                                 goto domain_and_file_run_fail;
00270                                         }
00271                                         proof->type = SECHK_ITEM_TYPE;
00272                                         proof->text = strdup(domain_proof->text);
00273                                         if (!proof->text) {
00274                                                 error = errno;
00275                                                 ERR(policy, "%s", strerror(ENOMEM));
00276                                                 goto domain_and_file_run_fail;
00277                                         }
00278                                         if (apol_vector_append(item->proof, (void *)proof) < 0) {
00279                                                 error = errno;
00280                                                 ERR(policy, "%s", strerror(ENOMEM));
00281                                                 goto domain_and_file_run_fail;
00282                                         }
00283                                 }
00284                                 for (k = 0; k < apol_vector_get_size(type_item->proof); k++) {
00285                                         sechk_proof_t *type_proof;
00286 
00287                                         type_proof = apol_vector_get_element(type_item->proof, k);
00288                                         proof = sechk_proof_new(NULL);
00289                                         if (!proof) {
00290                                                 error = errno;
00291                                                 ERR(policy, "%s", strerror(ENOMEM));
00292                                                 goto domain_and_file_run_fail;
00293                                         }
00294                                         proof->type = SECHK_ITEM_TYPE;
00295                                         proof->text = strdup(type_proof->text);
00296                                         if (!proof->text) {
00297                                                 error = errno;
00298                                                 ERR(policy, "%s", strerror(ENOMEM));
00299                                                 goto domain_and_file_run_fail;
00300                                         }
00301                                         if (apol_vector_append(item->proof, (void *)proof) < 0) {
00302                                                 error = errno;
00303                                                 ERR(policy, "%s", strerror(ENOMEM));
00304                                                 goto domain_and_file_run_fail;
00305                                         }
00306                                 }
00307                                 if (apol_vector_append(res->items, (void *)item) < 0) {
00308                                         error = errno;
00309                                         ERR(policy, "%s", strerror(ENOMEM));
00310                                         goto domain_and_file_run_fail;
00311                                 }
00312                         }
00313                 }
00314         }
00315 
00316         mod->result = res;
00317 
00318         if (apol_vector_get_size(res->items))
00319                 return 1;
00320         return 0;
00321 
00322       domain_and_file_run_fail:
00323         sechk_proof_free(proof);
00324         sechk_item_free(item);
00325         sechk_result_destroy(&res);
00326         errno = error;
00327         return -1;
00328 }
00329 
00330 int domain_and_file_print(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00331 {
00332         unsigned char outformat = 0x00;
00333         sechk_item_t *item = NULL;
00334         sechk_proof_t *proof = NULL;
00335         size_t i = 0, j = 0, k = 0, l = 0, num_items;
00336         qpol_type_t *type;
00337         qpol_policy_t *q = apol_policy_get_qpol(policy);
00338         const char *type_name;
00339 
00340         if (!mod || !policy) {
00341                 ERR(policy, "%s", "Invalid parameters");
00342                 errno = EINVAL;
00343                 return -1;
00344         }
00345         if (strcmp(mod_name, mod->name)) {
00346                 ERR(policy, "Wrong module (%s)", mod->name);
00347                 errno = EINVAL;
00348                 return -1;
00349         }
00350 
00351         outformat = mod->outputformat;
00352         num_items = apol_vector_get_size(mod->result->items);
00353 
00354         if (!mod->result) {
00355                 ERR(policy, "%s", "Module has not been run");
00356                 errno = EINVAL;
00357                 return -1;
00358         }
00359 
00360         if (!outformat || (outformat & SECHK_OUT_QUIET))
00361                 return 0;              /* not an error - no output is requested */
00362 
00363         if (outformat & SECHK_OUT_STATS) {
00364                 printf("Found %zd types.\n", num_items);
00365         }
00366         if (outformat & SECHK_OUT_LIST) {
00367                 printf("\n");
00368                 for (i = 0; i < num_items; i++) {
00369                         j++;
00370                         j %= 4;
00371                         item = apol_vector_get_element(mod->result->items, i);
00372                         type = (qpol_type_t *) item->item;
00373                         qpol_type_get_name(q, type, &type_name);
00374                         printf("%s%s", type_name, (char *)((j && i != num_items - 1) ? ", " : "\n"));
00375                 }
00376                 printf("\n");
00377         }
00378 
00379         if (outformat & SECHK_OUT_PROOF) {
00380                 printf("\n");
00381                 for (k = 0; k < num_items; k++) {
00382                         item = apol_vector_get_element(mod->result->items, k);
00383                         if (item) {
00384                                 type = item->item;
00385                                 qpol_type_get_name(q, type, &type_name);
00386                                 printf("%s\n", (char *)type_name);
00387                                 for (l = 0; l < apol_vector_get_size(item->proof); l++) {
00388                                         proof = apol_vector_get_element(item->proof, l);
00389                                         if (proof)
00390                                                 printf("\t%s\n", proof->text);
00391                                 }
00392                         }
00393                 }
00394                 printf("\n");
00395         }
00396 
00397         return 0;
00398 }