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