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