#include #include #include "handle.h" #include "private.h" #include "debug.h" #include #include #include #include #include "boolean_internal.h" static int bool_update(sepol_handle_t * handle, policydb_t * policydb, const sepol_bool_key_t * key, const sepol_bool_t * data) { const char *cname; char *name; int value; cond_bool_datum_t *datum; sepol_bool_key_unpack(key, &cname); name = strdup(cname); value = sepol_bool_get_value(data); if (!name) goto omem; datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(handle, "boolean %s no longer in policy", name); goto err; } if (value != 0 && value != 1) { ERR(handle, "illegal value %d for boolean %s", value, name); goto err; } free(name); datum->state = value; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: free(name); ERR(handle, "could not update boolean %s", cname); return STATUS_ERR; } static int bool_to_record(sepol_handle_t * handle, const policydb_t * policydb, int bool_idx, sepol_bool_t ** record) { const char *name = policydb->p_bool_val_to_name[bool_idx]; cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx]; int value = booldatum->state; sepol_bool_t *tmp_record = NULL; if (sepol_bool_create(handle, &tmp_record) < 0) goto err; if (sepol_bool_set_name(handle, tmp_record, name) < 0) goto err; sepol_bool_set_value(tmp_record, value); *record = tmp_record; return STATUS_SUCCESS; err: ERR(handle, "could not convert boolean %s to record", name); sepol_bool_free(tmp_record); return STATUS_ERR; } int sepol_bool_set(sepol_handle_t * handle, sepol_policydb_t * p, const sepol_bool_key_t * key, const sepol_bool_t * data) { policydb_t *policydb = &p->p; const char *name; sepol_bool_key_unpack(key, &name); if (bool_update(handle, policydb, key, data) < 0) goto err; if (evaluate_conds(policydb) < 0) { ERR(handle, "error while re-evaluating conditionals"); goto err; } return STATUS_SUCCESS; err: ERR(handle, "could not set boolean %s", name); return STATUS_ERR; } int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)), const sepol_policydb_t * p, unsigned int *response) { const policydb_t *policydb = &p->p; *response = policydb->p_bools.nprim; return STATUS_SUCCESS; } int sepol_bool_exists(sepol_handle_t * handle, const sepol_policydb_t * p, const sepol_bool_key_t * key, int *response) { const policydb_t *policydb = &p->p; const char *cname; char *name = NULL; sepol_bool_key_unpack(key, &cname); name = strdup(cname); if (!name) { ERR(handle, "out of memory, could not check " "if user %s exists", cname); return STATUS_ERR; } *response = (hashtab_search(policydb->p_bools.table, name) != NULL); free(name); return STATUS_SUCCESS; } int sepol_bool_query(sepol_handle_t * handle, const sepol_policydb_t * p, const sepol_bool_key_t * key, sepol_bool_t ** response) { const policydb_t *policydb = &p->p; cond_bool_datum_t *booldatum = NULL; const char *cname; char *name = NULL; sepol_bool_key_unpack(key, &cname); name = strdup(cname); if (!name) goto omem; booldatum = hashtab_search(policydb->p_bools.table, name); if (!booldatum) { *response = NULL; free(name); return STATUS_SUCCESS; } if (bool_to_record(handle, policydb, booldatum->s.value - 1, response) < 0) goto err; free(name); return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not query boolean %s", cname); free(name); return STATUS_ERR; } int sepol_bool_iterate(sepol_handle_t * handle, const sepol_policydb_t * p, int (*fn) (const sepol_bool_t * boolean, void *fn_arg), void *arg) { const policydb_t *policydb = &p->p; unsigned int nbools = policydb->p_bools.nprim; sepol_bool_t *boolean = NULL; unsigned int i; /* For each boolean */ for (i = 0; i < nbools; i++) { int status; if (bool_to_record(handle, policydb, i, &boolean) < 0) goto err; /* Invoke handler */ status = fn(boolean, arg); if (status < 0) goto err; sepol_bool_free(boolean); boolean = NULL; /* Handler requested exit */ if (status > 0) break; } return STATUS_SUCCESS; err: ERR(handle, "could not iterate over booleans"); sepol_bool_free(boolean); return STATUS_ERR; }