xref: /aosp_15_r20/external/selinux/libsemanage/src/database.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
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