xref: /aosp_15_r20/external/selinux/libsemanage/src/database_policydb.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Copyright (C) 2005 Red Hat, Inc. */
2*2d543d20SAndroid Build Coastguard Worker 
3*2d543d20SAndroid Build Coastguard Worker /* Object: dbase_policydb_t (Policy)
4*2d543d20SAndroid Build Coastguard Worker  * Implements: dbase_t (Database)
5*2d543d20SAndroid Build Coastguard Worker  */
6*2d543d20SAndroid Build Coastguard Worker 
7*2d543d20SAndroid Build Coastguard Worker struct dbase_policydb;
8*2d543d20SAndroid Build Coastguard Worker typedef struct dbase_policydb dbase_t;
9*2d543d20SAndroid Build Coastguard Worker #define DBASE_DEFINED
10*2d543d20SAndroid Build Coastguard Worker 
11*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
12*2d543d20SAndroid Build Coastguard Worker #include <stddef.h>
13*2d543d20SAndroid Build Coastguard Worker #include <string.h>
14*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
15*2d543d20SAndroid Build Coastguard Worker #include <stdio_ext.h>
16*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
17*2d543d20SAndroid Build Coastguard Worker 
18*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb.h>
19*2d543d20SAndroid Build Coastguard Worker 
20*2d543d20SAndroid Build Coastguard Worker #include "database_policydb.h"
21*2d543d20SAndroid Build Coastguard Worker #include "semanage_store.h"
22*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
23*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
24*2d543d20SAndroid Build Coastguard Worker 
25*2d543d20SAndroid Build Coastguard Worker /* POLICYDB dbase */
26*2d543d20SAndroid Build Coastguard Worker struct dbase_policydb {
27*2d543d20SAndroid Build Coastguard Worker 
28*2d543d20SAndroid Build Coastguard Worker         /* Backing path for read-only[0] and transaction[1] */
29*2d543d20SAndroid Build Coastguard Worker         const char *path[2];
30*2d543d20SAndroid Build Coastguard Worker 
31*2d543d20SAndroid Build Coastguard Worker 	/* Base record table */
32*2d543d20SAndroid Build Coastguard Worker 	record_table_t *rtable;
33*2d543d20SAndroid Build Coastguard Worker 
34*2d543d20SAndroid Build Coastguard Worker 	/* Policy extensions */
35*2d543d20SAndroid Build Coastguard Worker 	record_policydb_table_t *rptable;
36*2d543d20SAndroid Build Coastguard Worker 
37*2d543d20SAndroid Build Coastguard Worker 	sepol_policydb_t *policydb;
38*2d543d20SAndroid Build Coastguard Worker 
39*2d543d20SAndroid Build Coastguard Worker 	int cache_serial;
40*2d543d20SAndroid Build Coastguard Worker 	int modified;
41*2d543d20SAndroid Build Coastguard Worker 	int attached;
42*2d543d20SAndroid Build Coastguard Worker };
43*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_drop_cache(dbase_policydb_t * dbase)44*2d543d20SAndroid Build Coastguard Worker static void dbase_policydb_drop_cache(dbase_policydb_t * dbase)
45*2d543d20SAndroid Build Coastguard Worker {
46*2d543d20SAndroid Build Coastguard Worker 
47*2d543d20SAndroid Build Coastguard Worker 	if (dbase->cache_serial >= 0) {
48*2d543d20SAndroid Build Coastguard Worker 		sepol_policydb_free(dbase->policydb);
49*2d543d20SAndroid Build Coastguard Worker 		dbase->cache_serial = -1;
50*2d543d20SAndroid Build Coastguard Worker 		dbase->modified = 0;
51*2d543d20SAndroid Build Coastguard Worker 	}
52*2d543d20SAndroid Build Coastguard Worker }
53*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_set_serial(semanage_handle_t * handle,dbase_policydb_t * dbase)54*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_set_serial(semanage_handle_t * handle,
55*2d543d20SAndroid Build Coastguard Worker 				     dbase_policydb_t * dbase)
56*2d543d20SAndroid Build Coastguard Worker {
57*2d543d20SAndroid Build Coastguard Worker 
58*2d543d20SAndroid Build Coastguard Worker 	int cache_serial = handle->funcs->get_serial(handle);
59*2d543d20SAndroid Build Coastguard Worker 	if (cache_serial < 0) {
60*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "could not update cache serial");
61*2d543d20SAndroid Build Coastguard Worker 		return STATUS_ERR;
62*2d543d20SAndroid Build Coastguard Worker 	}
63*2d543d20SAndroid Build Coastguard Worker 
64*2d543d20SAndroid Build Coastguard Worker 	dbase->cache_serial = cache_serial;
65*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
66*2d543d20SAndroid Build Coastguard Worker }
67*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_needs_resync(semanage_handle_t * handle,dbase_policydb_t * dbase)68*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_needs_resync(semanage_handle_t * handle,
69*2d543d20SAndroid Build Coastguard Worker 				       dbase_policydb_t * dbase)
70*2d543d20SAndroid Build Coastguard Worker {
71*2d543d20SAndroid Build Coastguard Worker 
72*2d543d20SAndroid Build Coastguard Worker 	int cache_serial;
73*2d543d20SAndroid Build Coastguard Worker 
74*2d543d20SAndroid Build Coastguard Worker 	if (dbase->cache_serial < 0)
75*2d543d20SAndroid Build Coastguard Worker 		return 1;
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker 	cache_serial = handle->funcs->get_serial(handle);
78*2d543d20SAndroid Build Coastguard Worker 	if (cache_serial < 0)
79*2d543d20SAndroid Build Coastguard Worker 		return 1;
80*2d543d20SAndroid Build Coastguard Worker 
81*2d543d20SAndroid Build Coastguard Worker 	if (cache_serial != dbase->cache_serial) {
82*2d543d20SAndroid Build Coastguard Worker 		dbase_policydb_drop_cache(dbase);
83*2d543d20SAndroid Build Coastguard Worker 		dbase->cache_serial = -1;
84*2d543d20SAndroid Build Coastguard Worker 		return 1;
85*2d543d20SAndroid Build Coastguard Worker 	}
86*2d543d20SAndroid Build Coastguard Worker 	return 0;
87*2d543d20SAndroid Build Coastguard Worker }
88*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_cache(semanage_handle_t * handle,dbase_policydb_t * dbase)89*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_cache(semanage_handle_t * handle,
90*2d543d20SAndroid Build Coastguard Worker 				dbase_policydb_t * dbase)
91*2d543d20SAndroid Build Coastguard Worker {
92*2d543d20SAndroid Build Coastguard Worker 
93*2d543d20SAndroid Build Coastguard Worker 	FILE *fp = NULL;
94*2d543d20SAndroid Build Coastguard Worker 	sepol_policydb_t *policydb = NULL;
95*2d543d20SAndroid Build Coastguard Worker 	sepol_policy_file_t *pf = NULL;
96*2d543d20SAndroid Build Coastguard Worker 	const char *fname = NULL;
97*2d543d20SAndroid Build Coastguard Worker 
98*2d543d20SAndroid Build Coastguard Worker 	/* Check if cache is needed */
99*2d543d20SAndroid Build Coastguard Worker 	if (dbase->attached)
100*2d543d20SAndroid Build Coastguard Worker 		return STATUS_SUCCESS;
101*2d543d20SAndroid Build Coastguard Worker 
102*2d543d20SAndroid Build Coastguard Worker 	if (!dbase_policydb_needs_resync(handle, dbase))
103*2d543d20SAndroid Build Coastguard Worker 		return STATUS_SUCCESS;
104*2d543d20SAndroid Build Coastguard Worker 
105*2d543d20SAndroid Build Coastguard Worker 	fname = dbase->path[handle->is_in_transaction];
106*2d543d20SAndroid Build Coastguard Worker 
107*2d543d20SAndroid Build Coastguard Worker 	if (sepol_policydb_create(&policydb) < 0) {
108*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "could not create policydb object");
109*2d543d20SAndroid Build Coastguard Worker 		goto err;
110*2d543d20SAndroid Build Coastguard Worker 	}
111*2d543d20SAndroid Build Coastguard Worker 
112*2d543d20SAndroid Build Coastguard Worker 	/* Try opening file
113*2d543d20SAndroid Build Coastguard Worker 	 * ENOENT is not fatal - we just create an empty policydb */
114*2d543d20SAndroid Build Coastguard Worker 	fp = fopen(fname, "rb");
115*2d543d20SAndroid Build Coastguard Worker 	if (fp == NULL && errno != ENOENT) {
116*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "could not open %s for reading: %s",
117*2d543d20SAndroid Build Coastguard Worker 		    fname, strerror(errno));
118*2d543d20SAndroid Build Coastguard Worker 		goto err;
119*2d543d20SAndroid Build Coastguard Worker 	}
120*2d543d20SAndroid Build Coastguard Worker 
121*2d543d20SAndroid Build Coastguard Worker 	/* If the file was opened successfully, read a policydb */
122*2d543d20SAndroid Build Coastguard Worker 	if (fp != NULL) {
123*2d543d20SAndroid Build Coastguard Worker 		__fsetlocking(fp, FSETLOCKING_BYCALLER);
124*2d543d20SAndroid Build Coastguard Worker 		if (sepol_policy_file_create(&pf) < 0) {
125*2d543d20SAndroid Build Coastguard Worker 			ERR(handle, "could not create policy file object");
126*2d543d20SAndroid Build Coastguard Worker 			goto err;
127*2d543d20SAndroid Build Coastguard Worker 		}
128*2d543d20SAndroid Build Coastguard Worker 
129*2d543d20SAndroid Build Coastguard Worker 		sepol_policy_file_set_fp(pf, fp);
130*2d543d20SAndroid Build Coastguard Worker 		sepol_policy_file_set_handle(pf, handle->sepolh);
131*2d543d20SAndroid Build Coastguard Worker 
132*2d543d20SAndroid Build Coastguard Worker 		if (sepol_policydb_read(policydb, pf) < 0)
133*2d543d20SAndroid Build Coastguard Worker 			goto err;
134*2d543d20SAndroid Build Coastguard Worker 
135*2d543d20SAndroid Build Coastguard Worker 		sepol_policy_file_free(pf);
136*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
137*2d543d20SAndroid Build Coastguard Worker 		fp = NULL;
138*2d543d20SAndroid Build Coastguard Worker 	}
139*2d543d20SAndroid Build Coastguard Worker 
140*2d543d20SAndroid Build Coastguard Worker 	/* Update cache serial */
141*2d543d20SAndroid Build Coastguard Worker 	if (dbase_policydb_set_serial(handle, dbase) < 0)
142*2d543d20SAndroid Build Coastguard Worker 		goto err;
143*2d543d20SAndroid Build Coastguard Worker 
144*2d543d20SAndroid Build Coastguard Worker 	/* Update the database policydb */
145*2d543d20SAndroid Build Coastguard Worker 	dbase->policydb = policydb;
146*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
147*2d543d20SAndroid Build Coastguard Worker 
148*2d543d20SAndroid Build Coastguard Worker       err:
149*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not cache policy database");
150*2d543d20SAndroid Build Coastguard Worker 	if (fp)
151*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
152*2d543d20SAndroid Build Coastguard Worker 	sepol_policydb_free(policydb);
153*2d543d20SAndroid Build Coastguard Worker 	sepol_policy_file_free(pf);
154*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
155*2d543d20SAndroid Build Coastguard Worker }
156*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_flush(semanage_handle_t * handle,dbase_policydb_t * dbase)157*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_flush(semanage_handle_t * handle
158*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)),
159*2d543d20SAndroid Build Coastguard Worker 				dbase_policydb_t * dbase)
160*2d543d20SAndroid Build Coastguard Worker {
161*2d543d20SAndroid Build Coastguard Worker 
162*2d543d20SAndroid Build Coastguard Worker 	if (!dbase->modified)
163*2d543d20SAndroid Build Coastguard Worker 		return STATUS_SUCCESS;
164*2d543d20SAndroid Build Coastguard Worker 
165*2d543d20SAndroid Build Coastguard Worker 	dbase->modified = 0;
166*2d543d20SAndroid Build Coastguard Worker 
167*2d543d20SAndroid Build Coastguard Worker 	/* Stub */
168*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
169*2d543d20SAndroid Build Coastguard Worker }
170*2d543d20SAndroid Build Coastguard Worker 
171*2d543d20SAndroid Build Coastguard Worker /* Check if modified */
dbase_policydb_is_modified(dbase_policydb_t * dbase)172*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_is_modified(dbase_policydb_t * dbase)
173*2d543d20SAndroid Build Coastguard Worker {
174*2d543d20SAndroid Build Coastguard Worker 
175*2d543d20SAndroid Build Coastguard Worker 	return dbase->modified;
176*2d543d20SAndroid Build Coastguard Worker }
177*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_init(semanage_handle_t * handle,const char * path_ro,const char * path_rw,record_table_t * rtable,record_policydb_table_t * rptable,dbase_policydb_t ** dbase)178*2d543d20SAndroid Build Coastguard Worker int dbase_policydb_init(semanage_handle_t * handle,
179*2d543d20SAndroid Build Coastguard Worker 			const char *path_ro,
180*2d543d20SAndroid Build Coastguard Worker 			const char *path_rw,
181*2d543d20SAndroid Build Coastguard Worker 			record_table_t * rtable,
182*2d543d20SAndroid Build Coastguard Worker 			record_policydb_table_t * rptable,
183*2d543d20SAndroid Build Coastguard Worker 			dbase_policydb_t ** dbase)
184*2d543d20SAndroid Build Coastguard Worker {
185*2d543d20SAndroid Build Coastguard Worker 
186*2d543d20SAndroid Build Coastguard Worker 	dbase_policydb_t *tmp_dbase =
187*2d543d20SAndroid Build Coastguard Worker 	    (dbase_policydb_t *) malloc(sizeof(dbase_policydb_t));
188*2d543d20SAndroid Build Coastguard Worker 
189*2d543d20SAndroid Build Coastguard Worker 	if (!tmp_dbase)
190*2d543d20SAndroid Build Coastguard Worker 		goto omem;
191*2d543d20SAndroid Build Coastguard Worker 
192*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->path[0] = path_ro;
193*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->path[1] = path_rw;
194*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->rtable = rtable;
195*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->rptable = rptable;
196*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->policydb = NULL;
197*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->cache_serial = -1;
198*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->modified = 0;
199*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->attached = 0;
200*2d543d20SAndroid Build Coastguard Worker 	*dbase = tmp_dbase;
201*2d543d20SAndroid Build Coastguard Worker 
202*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
203*2d543d20SAndroid Build Coastguard Worker 
204*2d543d20SAndroid Build Coastguard Worker       omem:
205*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "out of memory, could not initialize policy database");
206*2d543d20SAndroid Build Coastguard Worker 	free(tmp_dbase);
207*2d543d20SAndroid Build Coastguard Worker 
208*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
209*2d543d20SAndroid Build Coastguard Worker }
210*2d543d20SAndroid Build Coastguard Worker 
211*2d543d20SAndroid Build Coastguard Worker /* Release dbase resources */
dbase_policydb_release(dbase_policydb_t * dbase)212*2d543d20SAndroid Build Coastguard Worker void dbase_policydb_release(dbase_policydb_t * dbase)
213*2d543d20SAndroid Build Coastguard Worker {
214*2d543d20SAndroid Build Coastguard Worker 
215*2d543d20SAndroid Build Coastguard Worker 	dbase_policydb_drop_cache(dbase);
216*2d543d20SAndroid Build Coastguard Worker 	free(dbase);
217*2d543d20SAndroid Build Coastguard Worker }
218*2d543d20SAndroid Build Coastguard Worker 
219*2d543d20SAndroid Build Coastguard Worker /* Attach to a shared policydb.
220*2d543d20SAndroid Build Coastguard Worker  * This implies drop_cache(),
221*2d543d20SAndroid Build Coastguard Worker  * and prevents flush() and drop_cache()
222*2d543d20SAndroid Build Coastguard Worker  * until detached. */
dbase_policydb_attach(dbase_policydb_t * dbase,sepol_policydb_t * policydb)223*2d543d20SAndroid Build Coastguard Worker void dbase_policydb_attach(dbase_policydb_t * dbase,
224*2d543d20SAndroid Build Coastguard Worker 			   sepol_policydb_t * policydb)
225*2d543d20SAndroid Build Coastguard Worker {
226*2d543d20SAndroid Build Coastguard Worker 
227*2d543d20SAndroid Build Coastguard Worker 	dbase->attached = 1;
228*2d543d20SAndroid Build Coastguard Worker 	dbase_policydb_drop_cache(dbase);
229*2d543d20SAndroid Build Coastguard Worker 	dbase->policydb = policydb;
230*2d543d20SAndroid Build Coastguard Worker }
231*2d543d20SAndroid Build Coastguard Worker 
232*2d543d20SAndroid Build Coastguard Worker /* Detach from a shared policdb.
233*2d543d20SAndroid Build Coastguard Worker  * This implies drop_cache. */
dbase_policydb_detach(dbase_policydb_t * dbase)234*2d543d20SAndroid Build Coastguard Worker void dbase_policydb_detach(dbase_policydb_t * dbase)
235*2d543d20SAndroid Build Coastguard Worker {
236*2d543d20SAndroid Build Coastguard Worker 
237*2d543d20SAndroid Build Coastguard Worker 	dbase->attached = 0;
238*2d543d20SAndroid Build Coastguard Worker 	dbase->modified = 0;
239*2d543d20SAndroid Build Coastguard Worker }
240*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_add(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key,const record_t * data)241*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_add(semanage_handle_t * handle,
242*2d543d20SAndroid Build Coastguard Worker 			      dbase_policydb_t * dbase,
243*2d543d20SAndroid Build Coastguard Worker 			      const record_key_t * key, const record_t * data)
244*2d543d20SAndroid Build Coastguard Worker {
245*2d543d20SAndroid Build Coastguard Worker 
246*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->add(handle->sepolh, dbase->policydb, key, data) < 0)
247*2d543d20SAndroid Build Coastguard Worker 		goto err;
248*2d543d20SAndroid Build Coastguard Worker 
249*2d543d20SAndroid Build Coastguard Worker 	dbase->modified = 1;
250*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
251*2d543d20SAndroid Build Coastguard Worker 
252*2d543d20SAndroid Build Coastguard Worker       err:
253*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not add record to the database");
254*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
255*2d543d20SAndroid Build Coastguard Worker }
256*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_set(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key,const record_t * data)257*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_set(semanage_handle_t * handle,
258*2d543d20SAndroid Build Coastguard Worker 			      dbase_policydb_t * dbase,
259*2d543d20SAndroid Build Coastguard Worker 			      const record_key_t * key, const record_t * data)
260*2d543d20SAndroid Build Coastguard Worker {
261*2d543d20SAndroid Build Coastguard Worker 
262*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->set(handle->sepolh, dbase->policydb, key, data) < 0)
263*2d543d20SAndroid Build Coastguard Worker 		goto err;
264*2d543d20SAndroid Build Coastguard Worker 
265*2d543d20SAndroid Build Coastguard Worker 	dbase->modified = 1;
266*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
267*2d543d20SAndroid Build Coastguard Worker 
268*2d543d20SAndroid Build Coastguard Worker       err:
269*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not set record value");
270*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
271*2d543d20SAndroid Build Coastguard Worker }
272*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_modify(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key,const record_t * data)273*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_modify(semanage_handle_t * handle,
274*2d543d20SAndroid Build Coastguard Worker 				 dbase_policydb_t * dbase,
275*2d543d20SAndroid Build Coastguard Worker 				 const record_key_t * key,
276*2d543d20SAndroid Build Coastguard Worker 				 const record_t * data)
277*2d543d20SAndroid Build Coastguard Worker {
278*2d543d20SAndroid Build Coastguard Worker 
279*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->modify(handle->sepolh,
280*2d543d20SAndroid Build Coastguard Worker 				   dbase->policydb, key, data) < 0)
281*2d543d20SAndroid Build Coastguard Worker 		goto err;
282*2d543d20SAndroid Build Coastguard Worker 
283*2d543d20SAndroid Build Coastguard Worker 	dbase->modified = 1;
284*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
285*2d543d20SAndroid Build Coastguard Worker 
286*2d543d20SAndroid Build Coastguard Worker       err:
287*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not modify record value");
288*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
289*2d543d20SAndroid Build Coastguard Worker }
290*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_del(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key)291*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_del(semanage_handle_t * handle
292*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)),
293*2d543d20SAndroid Build Coastguard Worker 			      dbase_policydb_t * dbase
294*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)),
295*2d543d20SAndroid Build Coastguard Worker 			      const record_key_t * key
296*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)))
297*2d543d20SAndroid Build Coastguard Worker {
298*2d543d20SAndroid Build Coastguard Worker 
299*2d543d20SAndroid Build Coastguard Worker 	/* Stub */
300*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
301*2d543d20SAndroid Build Coastguard Worker }
302*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_clear(semanage_handle_t * handle,dbase_policydb_t * dbase)303*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_clear(semanage_handle_t * handle
304*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)),
305*2d543d20SAndroid Build Coastguard Worker 				dbase_policydb_t * dbase
306*2d543d20SAndroid Build Coastguard Worker 				__attribute__ ((unused)))
307*2d543d20SAndroid Build Coastguard Worker {
308*2d543d20SAndroid Build Coastguard Worker 
309*2d543d20SAndroid Build Coastguard Worker 	/* Stub */
310*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
311*2d543d20SAndroid Build Coastguard Worker }
312*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_query(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key,record_t ** response)313*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_query(semanage_handle_t * handle,
314*2d543d20SAndroid Build Coastguard Worker 				dbase_policydb_t * dbase,
315*2d543d20SAndroid Build Coastguard Worker 				const record_key_t * key, record_t ** response)
316*2d543d20SAndroid Build Coastguard Worker {
317*2d543d20SAndroid Build Coastguard Worker 
318*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->query(handle->sepolh,
319*2d543d20SAndroid Build Coastguard Worker 				  dbase->policydb, key, response) < 0)
320*2d543d20SAndroid Build Coastguard Worker 		goto err;
321*2d543d20SAndroid Build Coastguard Worker 
322*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
323*2d543d20SAndroid Build Coastguard Worker 
324*2d543d20SAndroid Build Coastguard Worker       err:
325*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not query record value");
326*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
327*2d543d20SAndroid Build Coastguard Worker }
328*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_exists(semanage_handle_t * handle,dbase_policydb_t * dbase,const record_key_t * key,int * response)329*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_exists(semanage_handle_t * handle,
330*2d543d20SAndroid Build Coastguard Worker 				 dbase_policydb_t * dbase,
331*2d543d20SAndroid Build Coastguard Worker 				 const record_key_t * key, int *response)
332*2d543d20SAndroid Build Coastguard Worker {
333*2d543d20SAndroid Build Coastguard Worker 
334*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->exists(handle->sepolh,
335*2d543d20SAndroid Build Coastguard Worker 				   dbase->policydb, key, response) < 0)
336*2d543d20SAndroid Build Coastguard Worker 		goto err;
337*2d543d20SAndroid Build Coastguard Worker 
338*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
339*2d543d20SAndroid Build Coastguard Worker 
340*2d543d20SAndroid Build Coastguard Worker       err:
341*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not check if record exists");
342*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
343*2d543d20SAndroid Build Coastguard Worker }
344*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_count(semanage_handle_t * handle,dbase_policydb_t * dbase,unsigned int * response)345*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_count(semanage_handle_t * handle,
346*2d543d20SAndroid Build Coastguard Worker 				dbase_policydb_t * dbase,
347*2d543d20SAndroid Build Coastguard Worker 				unsigned int *response)
348*2d543d20SAndroid Build Coastguard Worker {
349*2d543d20SAndroid Build Coastguard Worker 
350*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->count(handle->sepolh,
351*2d543d20SAndroid Build Coastguard Worker 				  dbase->policydb, response) < 0)
352*2d543d20SAndroid Build Coastguard Worker 		goto err;
353*2d543d20SAndroid Build Coastguard Worker 
354*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
355*2d543d20SAndroid Build Coastguard Worker 
356*2d543d20SAndroid Build Coastguard Worker       err:
357*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not count the database records");
358*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
359*2d543d20SAndroid Build Coastguard Worker }
360*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_iterate(semanage_handle_t * handle,dbase_policydb_t * dbase,int (* fn)(const record_t * record,void * fn_arg),void * arg)361*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_iterate(semanage_handle_t * handle,
362*2d543d20SAndroid Build Coastguard Worker 				  dbase_policydb_t * dbase,
363*2d543d20SAndroid Build Coastguard Worker 				  int (*fn) (const record_t * record,
364*2d543d20SAndroid Build Coastguard Worker 					     void *fn_arg), void *arg)
365*2d543d20SAndroid Build Coastguard Worker {
366*2d543d20SAndroid Build Coastguard Worker 
367*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->iterate(handle->sepolh,
368*2d543d20SAndroid Build Coastguard Worker 				    dbase->policydb, fn, arg) < 0)
369*2d543d20SAndroid Build Coastguard Worker 		goto err;
370*2d543d20SAndroid Build Coastguard Worker 
371*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
372*2d543d20SAndroid Build Coastguard Worker 
373*2d543d20SAndroid Build Coastguard Worker       err:
374*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not iterate over records");
375*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
376*2d543d20SAndroid Build Coastguard Worker }
377*2d543d20SAndroid Build Coastguard Worker 
378*2d543d20SAndroid Build Coastguard Worker struct list_handler_arg {
379*2d543d20SAndroid Build Coastguard Worker 	semanage_handle_t *handle;
380*2d543d20SAndroid Build Coastguard Worker 	record_table_t *rtable;
381*2d543d20SAndroid Build Coastguard Worker 	record_t **records;
382*2d543d20SAndroid Build Coastguard Worker 	int pos;
383*2d543d20SAndroid Build Coastguard Worker };
384*2d543d20SAndroid Build Coastguard Worker 
list_handler(const record_t * record,void * varg)385*2d543d20SAndroid Build Coastguard Worker static int list_handler(const record_t * record, void *varg)
386*2d543d20SAndroid Build Coastguard Worker {
387*2d543d20SAndroid Build Coastguard Worker 
388*2d543d20SAndroid Build Coastguard Worker 	struct list_handler_arg *arg = (struct list_handler_arg *)varg;
389*2d543d20SAndroid Build Coastguard Worker 
390*2d543d20SAndroid Build Coastguard Worker 	if (arg->rtable->clone(arg->handle, record, &arg->records[arg->pos]) <
391*2d543d20SAndroid Build Coastguard Worker 	    0)
392*2d543d20SAndroid Build Coastguard Worker 		return -1;
393*2d543d20SAndroid Build Coastguard Worker 	arg->pos++;
394*2d543d20SAndroid Build Coastguard Worker 	return 0;
395*2d543d20SAndroid Build Coastguard Worker }
396*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_list(semanage_handle_t * handle,dbase_t * dbase,record_t *** records,unsigned int * count)397*2d543d20SAndroid Build Coastguard Worker static int dbase_policydb_list(semanage_handle_t * handle,
398*2d543d20SAndroid Build Coastguard Worker 			       dbase_t * dbase,
399*2d543d20SAndroid Build Coastguard Worker 			       record_t *** records, unsigned int *count)
400*2d543d20SAndroid Build Coastguard Worker {
401*2d543d20SAndroid Build Coastguard Worker 
402*2d543d20SAndroid Build Coastguard Worker 	record_t **tmp_records = NULL;
403*2d543d20SAndroid Build Coastguard Worker 	unsigned int tmp_count;
404*2d543d20SAndroid Build Coastguard Worker 	struct list_handler_arg list_arg;
405*2d543d20SAndroid Build Coastguard Worker 	list_arg.pos = 0;
406*2d543d20SAndroid Build Coastguard Worker 	list_arg.rtable = dbase->rtable;
407*2d543d20SAndroid Build Coastguard Worker 	list_arg.handle = handle;
408*2d543d20SAndroid Build Coastguard Worker 
409*2d543d20SAndroid Build Coastguard Worker 	if (dbase->rptable->count(handle->sepolh,
410*2d543d20SAndroid Build Coastguard Worker 				  dbase->policydb, &tmp_count) < 0)
411*2d543d20SAndroid Build Coastguard Worker 		goto err;
412*2d543d20SAndroid Build Coastguard Worker 
413*2d543d20SAndroid Build Coastguard Worker 	if (tmp_count > 0) {
414*2d543d20SAndroid Build Coastguard Worker 		tmp_records = (record_t **)
415*2d543d20SAndroid Build Coastguard Worker 		    calloc(tmp_count, sizeof(record_t *));
416*2d543d20SAndroid Build Coastguard Worker 
417*2d543d20SAndroid Build Coastguard Worker 		if (tmp_records == NULL)
418*2d543d20SAndroid Build Coastguard Worker 			goto omem;
419*2d543d20SAndroid Build Coastguard Worker 
420*2d543d20SAndroid Build Coastguard Worker 		list_arg.records = tmp_records;
421*2d543d20SAndroid Build Coastguard Worker 
422*2d543d20SAndroid Build Coastguard Worker 		if (dbase->rptable->iterate(handle->sepolh,
423*2d543d20SAndroid Build Coastguard Worker 					    dbase->policydb, list_handler,
424*2d543d20SAndroid Build Coastguard Worker 					    &list_arg) < 0) {
425*2d543d20SAndroid Build Coastguard Worker 			ERR(handle, "list handler could not extract record");
426*2d543d20SAndroid Build Coastguard Worker 			goto err;
427*2d543d20SAndroid Build Coastguard Worker 		}
428*2d543d20SAndroid Build Coastguard Worker 	}
429*2d543d20SAndroid Build Coastguard Worker 
430*2d543d20SAndroid Build Coastguard Worker 	*records = tmp_records;
431*2d543d20SAndroid Build Coastguard Worker 	*count = tmp_count;
432*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
433*2d543d20SAndroid Build Coastguard Worker 
434*2d543d20SAndroid Build Coastguard Worker       omem:
435*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "out of memory");
436*2d543d20SAndroid Build Coastguard Worker 
437*2d543d20SAndroid Build Coastguard Worker       err:
438*2d543d20SAndroid Build Coastguard Worker 	if (tmp_records) {
439*2d543d20SAndroid Build Coastguard Worker 		for (; list_arg.pos >= 0; list_arg.pos--)
440*2d543d20SAndroid Build Coastguard Worker 			dbase->rtable->free(tmp_records[list_arg.pos]);
441*2d543d20SAndroid Build Coastguard Worker 		free(tmp_records);
442*2d543d20SAndroid Build Coastguard Worker 	}
443*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not list records");
444*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
445*2d543d20SAndroid Build Coastguard Worker }
446*2d543d20SAndroid Build Coastguard Worker 
dbase_policydb_get_rtable(dbase_policydb_t * dbase)447*2d543d20SAndroid Build Coastguard Worker static record_table_t *dbase_policydb_get_rtable(dbase_policydb_t * dbase)
448*2d543d20SAndroid Build Coastguard Worker {
449*2d543d20SAndroid Build Coastguard Worker 
450*2d543d20SAndroid Build Coastguard Worker 	return dbase->rtable;
451*2d543d20SAndroid Build Coastguard Worker }
452*2d543d20SAndroid Build Coastguard Worker 
453*2d543d20SAndroid Build Coastguard Worker /* POLICYDB dbase - method table implementation */
454*2d543d20SAndroid Build Coastguard Worker dbase_table_t SEMANAGE_POLICYDB_DTABLE = {
455*2d543d20SAndroid Build Coastguard Worker 
456*2d543d20SAndroid Build Coastguard Worker 	/* Cache/Transactions */
457*2d543d20SAndroid Build Coastguard Worker 	.cache = dbase_policydb_cache,
458*2d543d20SAndroid Build Coastguard Worker 	.drop_cache = dbase_policydb_drop_cache,
459*2d543d20SAndroid Build Coastguard Worker 	.flush = dbase_policydb_flush,
460*2d543d20SAndroid Build Coastguard Worker 	.is_modified = dbase_policydb_is_modified,
461*2d543d20SAndroid Build Coastguard Worker 
462*2d543d20SAndroid Build Coastguard Worker 	/* Database Functionality */
463*2d543d20SAndroid Build Coastguard Worker 	.iterate = dbase_policydb_iterate,
464*2d543d20SAndroid Build Coastguard Worker 	.exists = dbase_policydb_exists,
465*2d543d20SAndroid Build Coastguard Worker 	.list = dbase_policydb_list,
466*2d543d20SAndroid Build Coastguard Worker 	.add = dbase_policydb_add,
467*2d543d20SAndroid Build Coastguard Worker 	.set = dbase_policydb_set,
468*2d543d20SAndroid Build Coastguard Worker 	.del = dbase_policydb_del,
469*2d543d20SAndroid Build Coastguard Worker 	.clear = dbase_policydb_clear,
470*2d543d20SAndroid Build Coastguard Worker 	.modify = dbase_policydb_modify,
471*2d543d20SAndroid Build Coastguard Worker 	.query = dbase_policydb_query,
472*2d543d20SAndroid Build Coastguard Worker 	.count = dbase_policydb_count,
473*2d543d20SAndroid Build Coastguard Worker 
474*2d543d20SAndroid Build Coastguard Worker 	/* Polymorphism */
475*2d543d20SAndroid Build Coastguard Worker 	.get_rtable = dbase_policydb_get_rtable
476*2d543d20SAndroid Build Coastguard Worker };
477