1#include <string.h> 2#include <stdlib.h> 3 4#include "handle.h" 5#include "private.h" 6#include "debug.h" 7 8#include <sepol/booleans.h> 9#include <sepol/policydb/hashtab.h> 10#include <sepol/policydb/policydb.h> 11#include <sepol/policydb/conditional.h> 12#include "boolean_internal.h" 13 14static int bool_update(sepol_handle_t * handle, 15 policydb_t * policydb, 16 const sepol_bool_key_t * key, const sepol_bool_t * data) 17{ 18 19 const char *cname; 20 char *name; 21 int value; 22 23 sepol_bool_key_unpack(key, &cname); 24 name = strdup(cname); 25 value = sepol_bool_get_value(data); 26 27 if (!name) 28 goto omem; 29 30 cond_bool_datum_t *datum = 31 hashtab_search(policydb->p_bools.table, name); 32 if (!datum) { 33 ERR(handle, "boolean %s no longer in policy", name); 34 goto err; 35 } 36 if (value != 0 && value != 1) { 37 ERR(handle, "illegal value %d for boolean %s", value, name); 38 goto err; 39 } 40 41 free(name); 42 datum->state = value; 43 return STATUS_SUCCESS; 44 45 omem: 46 ERR(handle, "out of memory"); 47 48 err: 49 free(name); 50 ERR(handle, "could not update boolean %s", cname); 51 return STATUS_ERR; 52} 53 54static int bool_to_record(sepol_handle_t * handle, 55 const policydb_t * policydb, 56 int bool_idx, sepol_bool_t ** record) 57{ 58 59 const char *name = policydb->p_bool_val_to_name[bool_idx]; 60 cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx]; 61 int value = booldatum->state; 62 63 sepol_bool_t *tmp_record = NULL; 64 65 if (sepol_bool_create(handle, &tmp_record) < 0) 66 goto err; 67 68 if (sepol_bool_set_name(handle, tmp_record, name) < 0) 69 goto err; 70 71 sepol_bool_set_value(tmp_record, value); 72 73 *record = tmp_record; 74 return STATUS_SUCCESS; 75 76 err: 77 ERR(handle, "could not convert boolean %s to record", name); 78 sepol_bool_free(tmp_record); 79 return STATUS_ERR; 80} 81 82int sepol_bool_set(sepol_handle_t * handle, 83 sepol_policydb_t * p, 84 const sepol_bool_key_t * key, const sepol_bool_t * data) 85{ 86 87 const char *name; 88 sepol_bool_key_unpack(key, &name); 89 90 policydb_t *policydb = &p->p; 91 if (bool_update(handle, policydb, key, data) < 0) 92 goto err; 93 94 if (evaluate_conds(policydb) < 0) { 95 ERR(handle, "error while re-evaluating conditionals"); 96 goto err; 97 } 98 99 return STATUS_SUCCESS; 100 101 err: 102 ERR(handle, "could not set boolean %s", name); 103 return STATUS_ERR; 104} 105 106int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)), 107 const sepol_policydb_t * p, unsigned int *response) 108{ 109 110 const policydb_t *policydb = &p->p; 111 *response = policydb->p_bools.nprim; 112 113 return STATUS_SUCCESS; 114} 115 116int sepol_bool_exists(sepol_handle_t * handle, 117 const sepol_policydb_t * p, 118 const sepol_bool_key_t * key, int *response) 119{ 120 121 const policydb_t *policydb = &p->p; 122 123 const char *cname; 124 char *name = NULL; 125 sepol_bool_key_unpack(key, &cname); 126 name = strdup(cname); 127 128 if (!name) { 129 ERR(handle, "out of memory, could not check " 130 "if user %s exists", cname); 131 return STATUS_ERR; 132 } 133 134 *response = (hashtab_search(policydb->p_bools.table, name) != NULL); 135 free(name); 136 return STATUS_SUCCESS; 137} 138 139int sepol_bool_query(sepol_handle_t * handle, 140 const sepol_policydb_t * p, 141 const sepol_bool_key_t * key, sepol_bool_t ** response) 142{ 143 144 const policydb_t *policydb = &p->p; 145 cond_bool_datum_t *booldatum = NULL; 146 147 const char *cname; 148 char *name = NULL; 149 sepol_bool_key_unpack(key, &cname); 150 name = strdup(cname); 151 152 if (!name) 153 goto omem; 154 155 booldatum = hashtab_search(policydb->p_bools.table, name); 156 if (!booldatum) { 157 *response = NULL; 158 return STATUS_SUCCESS; 159 } 160 161 if (bool_to_record(handle, policydb, 162 booldatum->s.value - 1, response) < 0) 163 goto err; 164 165 free(name); 166 return STATUS_SUCCESS; 167 168 omem: 169 ERR(handle, "out of memory"); 170 171 err: 172 ERR(handle, "could not query boolean %s", cname); 173 free(name); 174 return STATUS_ERR; 175} 176 177int sepol_bool_iterate(sepol_handle_t * handle, 178 const sepol_policydb_t * p, 179 int (*fn) (const sepol_bool_t * boolean, 180 void *fn_arg), void *arg) 181{ 182 183 const policydb_t *policydb = &p->p; 184 unsigned int nbools = policydb->p_bools.nprim; 185 sepol_bool_t *boolean = NULL; 186 unsigned int i; 187 188 /* For each boolean */ 189 for (i = 0; i < nbools; i++) { 190 191 int status; 192 193 if (bool_to_record(handle, policydb, i, &boolean) < 0) 194 goto err; 195 196 /* Invoke handler */ 197 status = fn(boolean, arg); 198 if (status < 0) 199 goto err; 200 201 sepol_bool_free(boolean); 202 boolean = NULL; 203 204 /* Handler requested exit */ 205 if (status > 0) 206 break; 207 } 208 209 return STATUS_SUCCESS; 210 211 err: 212 ERR(handle, "could not iterate over booleans"); 213 sepol_bool_free(boolean); 214 return STATUS_ERR; 215} 216