Home | History | Annotate | Download | only in src
      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