roles_wo_types.c

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Implementation of the roles without types 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 "roles_wo_types.h"
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 
00032 /* This string is the name of the module and should match the stem
00033  * of the file name; it should also match the prefix of all functions
00034  * defined in this module and the private data storage structure */
00035 static const char *const mod_name = "roles_wo_types";
00036 
00037 /* The register function registers all of a module's functions
00038  * with the library. */
00039 int roles_wo_types_register(sechk_lib_t * lib)
00040 {
00041         sechk_module_t *mod = NULL;
00042         sechk_fn_t *fn_struct = NULL;
00043 
00044         if (!lib) {
00045                 ERR(NULL, "%s", "No library");
00046                 errno = EINVAL;
00047                 return -1;
00048         }
00049 
00050         /* Modules are declared by the config file and their name and options
00051          * are stored in the module array.  The name is looked up to determine
00052          * where to store the function structures */
00053         mod = sechk_lib_get_module(mod_name, lib);
00054         if (!mod) {
00055                 ERR(NULL, "%s", "Module unknown");
00056                 errno = EINVAL;
00057                 return -1;
00058         }
00059         mod->parent_lib = lib;
00060 
00061         /* assign descriptions */
00062         mod->brief_description = "roles with no types";
00063         mod->detailed_description =
00064                 "--------------------------------------------------------------------------------\n"
00065                 "This module finds roles in the policy that have no types.  A role with no types \n"
00066                 "cannot form a valid context.\n";
00067         mod->opt_description =
00068                 "Module requirements:\n" "   none\n" "Module dependencies:\n" "   none\n" "Module options:\n" "   none\n";
00069         mod->severity = SECHK_SEV_LOW;
00070         /* register functions */
00071         fn_struct = sechk_fn_new();
00072         if (!fn_struct) {
00073                 ERR(NULL, "%s", strerror(ENOMEM));
00074                 errno = ENOMEM;
00075                 return -1;
00076         }
00077         fn_struct->name = strdup(SECHK_MOD_FN_INIT);
00078         if (!fn_struct->name) {
00079                 ERR(NULL, "%s", strerror(ENOMEM));
00080                 errno = ENOMEM;
00081                 return -1;
00082         }
00083         fn_struct->fn = roles_wo_types_init;
00084         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00085                 ERR(NULL, "%s", strerror(ENOMEM));
00086                 errno = ENOMEM;
00087                 return -1;
00088         }
00089 
00090         fn_struct = sechk_fn_new();
00091         if (!fn_struct) {
00092                 ERR(NULL, "%s", strerror(ENOMEM));
00093                 errno = ENOMEM;
00094                 return -1;
00095         }
00096         fn_struct->name = strdup(SECHK_MOD_FN_RUN);
00097         if (!fn_struct->name) {
00098                 ERR(NULL, "%s", strerror(ENOMEM));
00099                 errno = ENOMEM;
00100                 return -1;
00101         }
00102         fn_struct->fn = roles_wo_types_run;
00103         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00104                 ERR(NULL, "%s", strerror(ENOMEM));
00105                 errno = ENOMEM;
00106                 return -1;
00107         }
00108 
00109         mod->data_free = NULL;
00110 
00111         fn_struct = sechk_fn_new();
00112         if (!fn_struct) {
00113                 ERR(NULL, "%s", strerror(ENOMEM));
00114                 errno = ENOMEM;
00115                 return -1;
00116         }
00117         fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
00118         if (!fn_struct->name) {
00119                 ERR(NULL, "%s", strerror(ENOMEM));
00120                 errno = ENOMEM;
00121                 return -1;
00122         }
00123         fn_struct->fn = roles_wo_types_print;
00124         if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
00125                 ERR(NULL, "%s", strerror(ENOMEM));
00126                 errno = ENOMEM;
00127                 return -1;
00128         }
00129 
00130         return 0;
00131 }
00132 
00133 /* The init function creates the module's private data storage object
00134  * and initializes its values based on the options parsed in the config
00135  * file. */
00136 int roles_wo_types_init(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00137 {
00138         if (!mod || !policy) {
00139                 ERR(policy, "%s", "Ivalid parameters");
00140                 errno = EINVAL;
00141                 return -1;
00142         }
00143         if (strcmp(mod_name, mod->name)) {
00144                 ERR(policy, "Wrong module (%s)", mod->name);
00145                 errno = EINVAL;
00146                 return -1;
00147         }
00148 
00149         mod->data = NULL;
00150 
00151         return 0;
00152 }
00153 
00154 /* The run function performs the check. This function runs only once
00155  * even if called multiple times. This function allocates the result
00156  * structure and fills in all relavant item and proof data. */
00157 int roles_wo_types_run(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00158 {
00159         sechk_result_t *res = NULL;
00160         sechk_item_t *item = NULL;
00161         sechk_proof_t *proof = NULL;
00162         size_t i;
00163         apol_vector_t *role_vector;
00164         qpol_iterator_t *type_iter = NULL;
00165         int error = 0;
00166 
00167         if (!mod || !policy) {
00168                 ERR(policy, "%s", "Ivalid parameters");
00169                 errno = EINVAL;
00170                 return -1;
00171         }
00172         if (strcmp(mod_name, mod->name)) {
00173                 ERR(policy, "Wrong module (%s)", mod->name);
00174                 errno = EINVAL;
00175                 return -1;
00176         }
00177 
00178         /* if already run return */
00179         if (mod->result)
00180                 return 0;
00181 
00182         res = sechk_result_new();
00183         if (!res) {
00184                 ERR(policy, "%s", strerror(ENOMEM));
00185                 errno = ENOMEM;
00186                 return -1;
00187         }
00188         res->test_name = strdup(mod_name);
00189         if (!res->test_name) {
00190                 error = errno;
00191                 ERR(policy, "%s", strerror(ENOMEM));
00192                 goto roles_wo_types_run_fail;
00193         }
00194         res->item_type = SECHK_ITEM_ROLE;
00195         if (!(res->items = apol_vector_create(sechk_item_free))) {
00196                 error = errno;
00197                 ERR(policy, "%s", strerror(ENOMEM));
00198                 goto roles_wo_types_run_fail;
00199         }
00200 
00201         if (apol_role_get_by_query(policy, NULL, &role_vector) < 0) {
00202                 error = errno;
00203                 ERR(policy, "%s", strerror(ENOMEM));
00204                 goto roles_wo_types_run_fail;
00205         }
00206 
00207         for (i = 0; i < apol_vector_get_size(role_vector); i++) {
00208                 const qpol_role_t *role;
00209                 const char *role_name;
00210                 int at_end;
00211 
00212                 role = apol_vector_get_element(role_vector, i);
00213                 qpol_role_get_name(apol_policy_get_qpol(policy), role, &role_name);
00214 
00215                 if (!strcmp(role_name, "object_r"))
00216                         continue;
00217 
00218                 qpol_role_get_type_iter(apol_policy_get_qpol(policy), role, &type_iter);
00219                 at_end = qpol_iterator_end(type_iter);
00220                 qpol_iterator_destroy(&type_iter);
00221                 if (!at_end)
00222                         continue;
00223 
00224                 proof = sechk_proof_new(NULL);
00225                 if (!proof) {
00226                         error = errno;
00227                         ERR(policy, "%s", strerror(ENOMEM));
00228                         goto roles_wo_types_run_fail;
00229                 }
00230                 proof->type = SECHK_ITEM_ROLE;
00231                 asprintf(&proof->text, "role %s has no types", role_name);
00232                 item = sechk_item_new(NULL);
00233                 if (!item) {
00234                         error = errno;
00235                         ERR(policy, "%s", strerror(ENOMEM));
00236                         goto roles_wo_types_run_fail;
00237                 }
00238                 item->item = (void *)role;
00239                 item->test_result = 1;
00240                 if (!item->proof) {
00241                         if (!(item->proof = apol_vector_create(sechk_proof_free))) {
00242                                 error = errno;
00243                                 ERR(policy, "%s", strerror(ENOMEM));
00244                                 goto roles_wo_types_run_fail;
00245                         }
00246                 }
00247                 if (apol_vector_append(item->proof, (void *)proof) < 0) {
00248                         error = errno;
00249                         ERR(policy, "%s", strerror(ENOMEM));
00250                         goto roles_wo_types_run_fail;
00251                 }
00252                 if (apol_vector_append(res->items, (void *)item) < 0) {
00253                         error = errno;
00254                         ERR(policy, "%s", strerror(ENOMEM));
00255                         goto roles_wo_types_run_fail;
00256                 }
00257         }
00258         apol_vector_destroy(&role_vector);
00259 
00260         mod->result = res;
00261 
00262         if (apol_vector_get_size(res->items))
00263                 return 1;
00264         return 0;
00265 
00266       roles_wo_types_run_fail:
00267         sechk_proof_free(proof);
00268         sechk_item_free(item);
00269         sechk_result_destroy(&res);
00270         errno = error;
00271         return -1;
00272 }
00273 
00274 /* The print function generates the text printed in the
00275  * report and prints it to stdout. */
00276 int roles_wo_types_print(sechk_module_t * mod, apol_policy_t * policy, void *arg __attribute__ ((unused)))
00277 {
00278         unsigned char outformat = 0x00;
00279         sechk_item_t *item = NULL;
00280         size_t i = 0, j = 0, num_items;
00281         const qpol_role_t *role;
00282         const char *role_name;
00283 
00284         if (!mod || !policy) {
00285                 ERR(policy, "%s", "Invalid parameters");
00286                 errno = EINVAL;
00287                 return -1;
00288         }
00289         if (strcmp(mod_name, mod->name)) {
00290                 ERR(policy, "Wrong module (%s)", mod->name);
00291                 errno = EINVAL;
00292                 return -1;
00293         }
00294 
00295         outformat = mod->outputformat;
00296         num_items = apol_vector_get_size(mod->result->items);
00297 
00298         if (!outformat || (outformat & SECHK_OUT_QUIET))
00299                 return 0;              /* not an error - no output is requested */
00300 
00301         if (!mod->result) {
00302                 ERR(policy, "%s", "Module has not been run");
00303                 errno = EINVAL;
00304                 return -1;
00305         }
00306 
00307         /* display the statistics of the results */
00308         if (outformat & SECHK_OUT_STATS) {
00309                 printf("Found %zd roles.\n", num_items);
00310         }
00311         if (outformat & SECHK_OUT_PROOF) {
00312                 printf("\nThe following roles have no associated types:\n");
00313         }
00314         /* The list report component is a display of all items
00315          * found without any supporting proof. */
00316         if (outformat & (SECHK_OUT_LIST | SECHK_OUT_PROOF)) {
00317                 printf("\n");
00318                 for (i = 0; i < num_items; i++) {
00319                         j++;
00320                         j %= 4;
00321                         item = apol_vector_get_element(mod->result->items, i);
00322                         role = (qpol_role_t *) item->item;
00323                         qpol_role_get_name(apol_policy_get_qpol(policy), role, &role_name);
00324                         printf("%s%s", role_name, (char *)((j && i != num_items - 1) ? ", " : "\n"));
00325                 }
00326                 printf("\n");
00327         }
00328 
00329         return 0;
00330 }