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 14 static 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 54 static 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 82 int 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 106 int 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 116 int 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 139 int 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 free(name); 159 return STATUS_SUCCESS; 160 } 161 162 if (bool_to_record(handle, policydb, 163 booldatum->s.value - 1, response) < 0) 164 goto err; 165 166 free(name); 167 return STATUS_SUCCESS; 168 169 omem: 170 ERR(handle, "out of memory"); 171 172 err: 173 ERR(handle, "could not query boolean %s", cname); 174 free(name); 175 return STATUS_ERR; 176 } 177 178 int sepol_bool_iterate(sepol_handle_t * handle, 179 const sepol_policydb_t * p, 180 int (*fn) (const sepol_bool_t * boolean, 181 void *fn_arg), void *arg) 182 { 183 184 const policydb_t *policydb = &p->p; 185 unsigned int nbools = policydb->p_bools.nprim; 186 sepol_bool_t *boolean = NULL; 187 unsigned int i; 188 189 /* For each boolean */ 190 for (i = 0; i < nbools; i++) { 191 192 int status; 193 194 if (bool_to_record(handle, policydb, i, &boolean) < 0) 195 goto err; 196 197 /* Invoke handler */ 198 status = fn(boolean, arg); 199 if (status < 0) 200 goto err; 201 202 sepol_bool_free(boolean); 203 boolean = NULL; 204 205 /* Handler requested exit */ 206 if (status > 0) 207 break; 208 } 209 210 return STATUS_SUCCESS; 211 212 err: 213 ERR(handle, "could not iterate over booleans"); 214 sepol_bool_free(boolean); 215 return STATUS_ERR; 216 } 217