database.c revision 13cd4c8960688af11ad23b4c946149015c80d549
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
9static 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
24static 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
49static inline int exit_ro(semanage_handle_t * handle, dbase_config_t * dconfig)
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
61static 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
82int 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
96int 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
110int 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
123int 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, dconfig);
133		return STATUS_ERR;
134	}
135
136	return exit_ro(handle, dconfig);
137}
138
139int 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, dconfig);
149		return STATUS_ERR;
150	}
151
152	return exit_ro(handle, dconfig);
153}
154
155int 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, dconfig);
164		return STATUS_ERR;
165	}
166
167	return exit_ro(handle, dconfig);
168}
169
170int 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, dconfig);
181		return STATUS_ERR;
182	}
183
184	return exit_ro(handle, dconfig);
185}
186
187int 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, dconfig);
197		return STATUS_ERR;
198	}
199
200	return exit_ro(handle, dconfig);
201}
202