Home | History | Annotate | Download | only in src
      1 /* Copyright (C) 2005 Red Hat, Inc. */
      2 
      3 #include <semanage/handle.h>
      4 #include "semanage_store.h"
      5 #include "semanage_conf.h"
      6 #include "database.h"
      7 #include "debug.h"
      8 
      9 static int assert_init(semanage_handle_t * handle, dbase_config_t * dconfig)
     10 {
     11 
     12 	if (dconfig->dtable == NULL) {
     13 
     14 		ERR(handle,
     15 		    "A direct or server connection is needed "
     16 		    "to use this function - please call "
     17 		    "the corresponding connect() method");
     18 		return STATUS_ERR;
     19 	}
     20 
     21 	return STATUS_SUCCESS;
     22 }
     23 
     24 static int enter_ro(semanage_handle_t * handle, dbase_config_t * dconfig)
     25 {
     26 
     27 	if (assert_init(handle, dconfig) < 0)
     28 		goto err;
     29 
     30 	if (!handle->is_in_transaction &&
     31 	    handle->conf->store_type == SEMANAGE_CON_DIRECT) {
     32 
     33 		if (semanage_get_active_lock(handle) < 0) {
     34 			ERR(handle, "could not get the active lock");
     35 			goto err;
     36 		}
     37 	}
     38 
     39 	if (dconfig->dtable->cache(handle, dconfig->dbase) < 0)
     40 		goto err;
     41 
     42 	return STATUS_SUCCESS;
     43 
     44       err:
     45 	ERR(handle, "could not enter read-only section");
     46 	return STATUS_ERR;
     47 }
     48 
     49 static inline int exit_ro(semanage_handle_t * handle)
     50 {
     51 
     52 	int commit_num = handle->funcs->get_serial(handle);
     53 
     54 	if (!handle->is_in_transaction &&
     55 	    handle->conf->store_type == SEMANAGE_CON_DIRECT)
     56 		semanage_release_active_lock(handle);
     57 
     58 	return commit_num;
     59 }
     60 
     61 static int enter_rw(semanage_handle_t * handle, dbase_config_t * dconfig)
     62 {
     63 
     64 	if (assert_init(handle, dconfig) < 0)
     65 		goto err;
     66 
     67 	if (!handle->is_in_transaction) {
     68 		ERR(handle, "this operation requires a transaction");
     69 		goto err;
     70 	}
     71 
     72 	if (dconfig->dtable->cache(handle, dconfig->dbase) < 0)
     73 		goto err;
     74 
     75 	return STATUS_SUCCESS;
     76 
     77       err:
     78 	ERR(handle, "could not enter read-write section");
     79 	return STATUS_ERR;
     80 }
     81 
     82 int dbase_modify(semanage_handle_t * handle,
     83 		 dbase_config_t * dconfig,
     84 		 const record_key_t * key, const record_t * data)
     85 {
     86 
     87 	if (enter_rw(handle, dconfig) < 0)
     88 		return STATUS_ERR;
     89 
     90 	if (dconfig->dtable->modify(handle, dconfig->dbase, key, data) < 0)
     91 		return STATUS_ERR;
     92 
     93 	return STATUS_SUCCESS;
     94 }
     95 
     96 int dbase_set(semanage_handle_t * handle,
     97 	      dbase_config_t * dconfig,
     98 	      const record_key_t * key, const record_t * data)
     99 {
    100 
    101 	if (enter_rw(handle, dconfig) < 0)
    102 		return STATUS_ERR;
    103 
    104 	if (dconfig->dtable->set(handle, dconfig->dbase, key, data) < 0)
    105 		return STATUS_ERR;
    106 
    107 	return STATUS_SUCCESS;
    108 }
    109 
    110 int dbase_del(semanage_handle_t * handle,
    111 	      dbase_config_t * dconfig, const record_key_t * key)
    112 {
    113 
    114 	if (enter_rw(handle, dconfig) < 0)
    115 		return STATUS_ERR;
    116 
    117 	if (dconfig->dtable->del(handle, dconfig->dbase, key) < 0)
    118 		return STATUS_ERR;
    119 
    120 	return STATUS_SUCCESS;
    121 }
    122 
    123 int dbase_query(semanage_handle_t * handle,
    124 		dbase_config_t * dconfig,
    125 		const record_key_t * key, record_t ** response)
    126 {
    127 
    128 	if (enter_ro(handle, dconfig) < 0)
    129 		return STATUS_ERR;
    130 
    131 	if (dconfig->dtable->query(handle, dconfig->dbase, key, response) < 0) {
    132 		exit_ro(handle);
    133 		return STATUS_ERR;
    134 	}
    135 
    136 	return exit_ro(handle);
    137 }
    138 
    139 int dbase_exists(semanage_handle_t * handle,
    140 		 dbase_config_t * dconfig,
    141 		 const record_key_t * key, int *response)
    142 {
    143 
    144 	if (enter_ro(handle, dconfig) < 0)
    145 		return STATUS_ERR;
    146 
    147 	if (dconfig->dtable->exists(handle, dconfig->dbase, key, response) < 0) {
    148 		exit_ro(handle);
    149 		return STATUS_ERR;
    150 	}
    151 
    152 	return exit_ro(handle);
    153 }
    154 
    155 int dbase_count(semanage_handle_t * handle,
    156 		dbase_config_t * dconfig, unsigned int *response)
    157 {
    158 
    159 	if (enter_ro(handle, dconfig) < 0)
    160 		return STATUS_ERR;
    161 
    162 	if (dconfig->dtable->count(handle, dconfig->dbase, response) < 0) {
    163 		exit_ro(handle);
    164 		return STATUS_ERR;
    165 	}
    166 
    167 	return exit_ro(handle);
    168 }
    169 
    170 int dbase_iterate(semanage_handle_t * handle,
    171 		  dbase_config_t * dconfig,
    172 		  int (*fn) (const record_t * record,
    173 			     void *fn_arg), void *fn_arg)
    174 {
    175 
    176 	if (enter_ro(handle, dconfig) < 0)
    177 		return STATUS_ERR;
    178 
    179 	if (dconfig->dtable->iterate(handle, dconfig->dbase, fn, fn_arg) < 0) {
    180 		exit_ro(handle);
    181 		return STATUS_ERR;
    182 	}
    183 
    184 	return exit_ro(handle);
    185 }
    186 
    187 int dbase_list(semanage_handle_t * handle,
    188 	       dbase_config_t * dconfig,
    189 	       record_t *** records, unsigned int *count)
    190 {
    191 
    192 	if (enter_ro(handle, dconfig) < 0)
    193 		return STATUS_ERR;
    194 
    195 	if (dconfig->dtable->list(handle, dconfig->dbase, records, count) < 0) {
    196 		exit_ro(handle);
    197 		return STATUS_ERR;
    198 	}
    199 
    200 	return exit_ro(handle);
    201 }
    202