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