xref: /aosp_15_r20/external/selinux/libsemanage/src/database_activedb.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_activedb_t (Active/Kernel)
4*2d543d20SAndroid Build Coastguard Worker  * Extends: dbase_llist_t (Linked List)
5*2d543d20SAndroid Build Coastguard Worker  * Implements: dbase_t (Database)
6*2d543d20SAndroid Build Coastguard Worker  */
7*2d543d20SAndroid Build Coastguard Worker 
8*2d543d20SAndroid Build Coastguard Worker struct dbase_activedb;
9*2d543d20SAndroid Build Coastguard Worker typedef struct dbase_activedb dbase_t;
10*2d543d20SAndroid Build Coastguard Worker #define DBASE_DEFINED
11*2d543d20SAndroid Build Coastguard Worker 
12*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
13*2d543d20SAndroid Build Coastguard Worker #include <string.h>
14*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
15*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
16*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
17*2d543d20SAndroid Build Coastguard Worker #include "database_activedb.h"
18*2d543d20SAndroid Build Coastguard Worker #include "database_llist.h"
19*2d543d20SAndroid Build Coastguard Worker 
20*2d543d20SAndroid Build Coastguard Worker /* ACTIVEDB dbase */
21*2d543d20SAndroid Build Coastguard Worker struct dbase_activedb {
22*2d543d20SAndroid Build Coastguard Worker 
23*2d543d20SAndroid Build Coastguard Worker 	/* Parent object - must always be
24*2d543d20SAndroid Build Coastguard Worker 	 * the first field - here we are using
25*2d543d20SAndroid Build Coastguard Worker 	 * a linked list to store the records */
26*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_t llist;
27*2d543d20SAndroid Build Coastguard Worker 
28*2d543d20SAndroid Build Coastguard Worker 	/* ACTIVEDB extension */
29*2d543d20SAndroid Build Coastguard Worker 	record_activedb_table_t *ratable;
30*2d543d20SAndroid Build Coastguard Worker };
31*2d543d20SAndroid Build Coastguard Worker 
dbase_activedb_cache(semanage_handle_t * handle,dbase_activedb_t * dbase)32*2d543d20SAndroid Build Coastguard Worker static int dbase_activedb_cache(semanage_handle_t * handle,
33*2d543d20SAndroid Build Coastguard Worker 				dbase_activedb_t * dbase)
34*2d543d20SAndroid Build Coastguard Worker {
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker 	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
37*2d543d20SAndroid Build Coastguard Worker 	record_activedb_table_t *ratable = dbase->ratable;
38*2d543d20SAndroid Build Coastguard Worker 
39*2d543d20SAndroid Build Coastguard Worker 	record_t **records = NULL;
40*2d543d20SAndroid Build Coastguard Worker 	unsigned int rcount = 0;
41*2d543d20SAndroid Build Coastguard Worker 	unsigned int i = 0;
42*2d543d20SAndroid Build Coastguard Worker 
43*2d543d20SAndroid Build Coastguard Worker 	/* Already cached */
44*2d543d20SAndroid Build Coastguard Worker 	if (!dbase_llist_needs_resync(handle, &dbase->llist))
45*2d543d20SAndroid Build Coastguard Worker 		return STATUS_SUCCESS;
46*2d543d20SAndroid Build Coastguard Worker 
47*2d543d20SAndroid Build Coastguard Worker 	/* Update cache serial */
48*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_cache_init(&dbase->llist);
49*2d543d20SAndroid Build Coastguard Worker 	if (dbase_llist_set_serial(handle, &dbase->llist) < 0)
50*2d543d20SAndroid Build Coastguard Worker 		goto err;
51*2d543d20SAndroid Build Coastguard Worker 
52*2d543d20SAndroid Build Coastguard Worker 	/* Fetch the entire list */
53*2d543d20SAndroid Build Coastguard Worker 	if (ratable->read_list(handle, &records, &rcount) < 0)
54*2d543d20SAndroid Build Coastguard Worker 		goto err;
55*2d543d20SAndroid Build Coastguard Worker 
56*2d543d20SAndroid Build Coastguard Worker 	/* Add records one by one */
57*2d543d20SAndroid Build Coastguard Worker 	for (; i < rcount; i++) {
58*2d543d20SAndroid Build Coastguard Worker 		if (dbase_llist_cache_prepend(handle, &dbase->llist, records[i])
59*2d543d20SAndroid Build Coastguard Worker 		    < 0)
60*2d543d20SAndroid Build Coastguard Worker 			goto err;
61*2d543d20SAndroid Build Coastguard Worker 		rtable->free(records[i]);
62*2d543d20SAndroid Build Coastguard Worker 	}
63*2d543d20SAndroid Build Coastguard Worker 
64*2d543d20SAndroid Build Coastguard Worker 	free(records);
65*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
66*2d543d20SAndroid Build Coastguard Worker 
67*2d543d20SAndroid Build Coastguard Worker       err:
68*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not cache active database");
69*2d543d20SAndroid Build Coastguard Worker 	for (; i < rcount; i++)
70*2d543d20SAndroid Build Coastguard Worker 		rtable->free(records[i]);
71*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_drop_cache(&dbase->llist);
72*2d543d20SAndroid Build Coastguard Worker 	free(records);
73*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
74*2d543d20SAndroid Build Coastguard Worker }
75*2d543d20SAndroid Build Coastguard Worker 
dbase_activedb_flush(semanage_handle_t * handle,dbase_activedb_t * dbase)76*2d543d20SAndroid Build Coastguard Worker static int dbase_activedb_flush(semanage_handle_t * handle,
77*2d543d20SAndroid Build Coastguard Worker 				dbase_activedb_t * dbase)
78*2d543d20SAndroid Build Coastguard Worker {
79*2d543d20SAndroid Build Coastguard Worker 
80*2d543d20SAndroid Build Coastguard Worker 	record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
81*2d543d20SAndroid Build Coastguard Worker 	record_activedb_table_t *ratable = dbase->ratable;
82*2d543d20SAndroid Build Coastguard Worker 
83*2d543d20SAndroid Build Coastguard Worker 	record_t **records = NULL;
84*2d543d20SAndroid Build Coastguard Worker 	unsigned int rcount = 0;
85*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
86*2d543d20SAndroid Build Coastguard Worker 
87*2d543d20SAndroid Build Coastguard Worker 	/* Not cached, or not modified - flush is not necessary */
88*2d543d20SAndroid Build Coastguard Worker 	if (!dbase_llist_is_modified(&dbase->llist))
89*2d543d20SAndroid Build Coastguard Worker 		return STATUS_SUCCESS;
90*2d543d20SAndroid Build Coastguard Worker 
91*2d543d20SAndroid Build Coastguard Worker 	/* Fetch list */
92*2d543d20SAndroid Build Coastguard Worker 	if (dbase_llist_list(handle, &dbase->llist, &records, &rcount) < 0)
93*2d543d20SAndroid Build Coastguard Worker 		goto err;
94*2d543d20SAndroid Build Coastguard Worker 
95*2d543d20SAndroid Build Coastguard Worker 	/* Commit */
96*2d543d20SAndroid Build Coastguard Worker 	if (ratable->commit_list(handle, records, rcount) < 0)
97*2d543d20SAndroid Build Coastguard Worker 		goto err;
98*2d543d20SAndroid Build Coastguard Worker 
99*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < rcount; i++)
100*2d543d20SAndroid Build Coastguard Worker 		rtable->free(records[i]);
101*2d543d20SAndroid Build Coastguard Worker 	free(records);
102*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_set_modified(&dbase->llist, 0);
103*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
104*2d543d20SAndroid Build Coastguard Worker 
105*2d543d20SAndroid Build Coastguard Worker       err:
106*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < rcount; i++)
107*2d543d20SAndroid Build Coastguard Worker 		rtable->free(records[i]);
108*2d543d20SAndroid Build Coastguard Worker 	free(records);
109*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not flush active database");
110*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
111*2d543d20SAndroid Build Coastguard Worker }
112*2d543d20SAndroid Build Coastguard Worker 
dbase_activedb_init(semanage_handle_t * handle,record_table_t * rtable,record_activedb_table_t * ratable,dbase_activedb_t ** dbase)113*2d543d20SAndroid Build Coastguard Worker int dbase_activedb_init(semanage_handle_t * handle,
114*2d543d20SAndroid Build Coastguard Worker 			record_table_t * rtable,
115*2d543d20SAndroid Build Coastguard Worker 			record_activedb_table_t * ratable,
116*2d543d20SAndroid Build Coastguard Worker 			dbase_activedb_t ** dbase)
117*2d543d20SAndroid Build Coastguard Worker {
118*2d543d20SAndroid Build Coastguard Worker 
119*2d543d20SAndroid Build Coastguard Worker 	dbase_activedb_t *tmp_dbase =
120*2d543d20SAndroid Build Coastguard Worker 	    (dbase_activedb_t *) malloc(sizeof(dbase_activedb_t));
121*2d543d20SAndroid Build Coastguard Worker 
122*2d543d20SAndroid Build Coastguard Worker 	if (!tmp_dbase)
123*2d543d20SAndroid Build Coastguard Worker 		goto omem;
124*2d543d20SAndroid Build Coastguard Worker 
125*2d543d20SAndroid Build Coastguard Worker 	tmp_dbase->ratable = ratable;
126*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_ACTIVEDB_DTABLE);
127*2d543d20SAndroid Build Coastguard Worker 
128*2d543d20SAndroid Build Coastguard Worker 	*dbase = tmp_dbase;
129*2d543d20SAndroid Build Coastguard Worker 
130*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
131*2d543d20SAndroid Build Coastguard Worker 
132*2d543d20SAndroid Build Coastguard Worker       omem:
133*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "out of memory, could not initialize active database");
134*2d543d20SAndroid Build Coastguard Worker 	free(tmp_dbase);
135*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
136*2d543d20SAndroid Build Coastguard Worker }
137*2d543d20SAndroid Build Coastguard Worker 
138*2d543d20SAndroid Build Coastguard Worker /* Release dbase resources */
dbase_activedb_release(dbase_activedb_t * dbase)139*2d543d20SAndroid Build Coastguard Worker void dbase_activedb_release(dbase_activedb_t * dbase)
140*2d543d20SAndroid Build Coastguard Worker {
141*2d543d20SAndroid Build Coastguard Worker 
142*2d543d20SAndroid Build Coastguard Worker 	dbase_llist_drop_cache(&dbase->llist);
143*2d543d20SAndroid Build Coastguard Worker 	free(dbase);
144*2d543d20SAndroid Build Coastguard Worker }
145*2d543d20SAndroid Build Coastguard Worker 
146*2d543d20SAndroid Build Coastguard Worker /* ACTIVEDB dbase - method table implementation */
147*2d543d20SAndroid Build Coastguard Worker dbase_table_t SEMANAGE_ACTIVEDB_DTABLE = {
148*2d543d20SAndroid Build Coastguard Worker 
149*2d543d20SAndroid Build Coastguard Worker 	/* Cache/Transactions */
150*2d543d20SAndroid Build Coastguard Worker 	.cache = dbase_activedb_cache,
151*2d543d20SAndroid Build Coastguard Worker 	.drop_cache = (void *)dbase_llist_drop_cache,
152*2d543d20SAndroid Build Coastguard Worker 	.flush = dbase_activedb_flush,
153*2d543d20SAndroid Build Coastguard Worker 	.is_modified = (void *)dbase_llist_is_modified,
154*2d543d20SAndroid Build Coastguard Worker 
155*2d543d20SAndroid Build Coastguard Worker 	/* Database API */
156*2d543d20SAndroid Build Coastguard Worker 	.iterate = (void *)dbase_llist_iterate,
157*2d543d20SAndroid Build Coastguard Worker 	.exists = (void *)dbase_llist_exists,
158*2d543d20SAndroid Build Coastguard Worker 	.list = (void *)dbase_llist_list,
159*2d543d20SAndroid Build Coastguard Worker 	.add = (void *)dbase_llist_add,
160*2d543d20SAndroid Build Coastguard Worker 	.set = (void *)dbase_llist_set,
161*2d543d20SAndroid Build Coastguard Worker 	.del = (void *)dbase_llist_del,
162*2d543d20SAndroid Build Coastguard Worker 	.clear = (void *)dbase_llist_clear,
163*2d543d20SAndroid Build Coastguard Worker 	.modify = (void *)dbase_llist_modify,
164*2d543d20SAndroid Build Coastguard Worker 	.query = (void *)dbase_llist_query,
165*2d543d20SAndroid Build Coastguard Worker 	.count = (void *)dbase_llist_count,
166*2d543d20SAndroid Build Coastguard Worker 
167*2d543d20SAndroid Build Coastguard Worker 	/* Polymorphism */
168*2d543d20SAndroid Build Coastguard Worker 	.get_rtable = (void *)dbase_llist_get_rtable
169*2d543d20SAndroid Build Coastguard Worker };
170