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