#include <string.h>
#include <stdlib.h>
#include "handle.h"
#include "private.h"
#include "debug.h"
#include <sepol/booleans.h>
#include <sepol/policydb/hashtab.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#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;
sepol_bool_key_unpack(key, &cname);
name = strdup(cname);
value = sepol_bool_get_value(data);
if (!name)
goto omem;
cond_bool_datum_t *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)
{
const char *name;
sepol_bool_key_unpack(key, &name);
policydb_t *policydb = &p->p;
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;
handle = NULL;
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;
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;
}