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