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
assert_init(semanage_handle_t * handle,dbase_config_t * dconfig)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
enter_ro(semanage_handle_t * handle,dbase_config_t * dconfig)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
exit_ro(semanage_handle_t * handle)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
enter_rw(semanage_handle_t * handle,dbase_config_t * dconfig)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
dbase_modify(semanage_handle_t * handle,dbase_config_t * dconfig,const record_key_t * key,const record_t * data)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
dbase_set(semanage_handle_t * handle,dbase_config_t * dconfig,const record_key_t * key,const record_t * data)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
dbase_del(semanage_handle_t * handle,dbase_config_t * dconfig,const record_key_t * key)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
dbase_query(semanage_handle_t * handle,dbase_config_t * dconfig,const record_key_t * key,record_t ** response)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
dbase_exists(semanage_handle_t * handle,dbase_config_t * dconfig,const record_key_t * key,int * response)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
dbase_count(semanage_handle_t * handle,dbase_config_t * dconfig,unsigned int * response)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
dbase_iterate(semanage_handle_t * handle,dbase_config_t * dconfig,int (* fn)(const record_t * record,void * fn_arg),void * fn_arg)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
dbase_list(semanage_handle_t * handle,dbase_config_t * dconfig,record_t *** records,unsigned int * count)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