1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 #ifndef _SEMANAGE_DATABASE_H_
4 #define _SEMANAGE_DATABASE_H_
5 
6 #ifndef DBASE_RECORD_DEFINED
7 typedef void *record_t;
8 typedef void *record_key_t;
9 #define DBASE_RECORD_DEFINED
10 #endif
11 
12 #ifndef DBASE_DEFINED
13 typedef void *dbase_t;
14 #define DBASE_DEFINED
15 #endif
16 
17 /* Circular dependency */
18 struct semanage_handle;
19 
20 /* RECORD interface - method table */
21 typedef struct record_table {
22 
23 	/* Create a record */
24 	int (*create) (struct semanage_handle * handle, record_t ** rec);
25 
26 	/* Extract key from record */
27 	int (*key_extract) (struct semanage_handle * handle,
28 			    const record_t * rec, record_key_t ** key);
29 
30 	/* Free record key */
31 	void (*key_free) (record_key_t * key);
32 
33 	/* Return 0 if the record matches the key,
34 	 * -1 if the key represents a record that should
35 	 * be ordered before this record, and 1 if vice-versa */
36 	int (*compare) (const record_t * rec, const record_key_t * key);
37 
38 	/* Return 0 if the record matches record2,
39 	 * -1 if record2 should be ordered before this record,
40 	 * and 1 if vice-versa */
41 	int (*compare2) (const record_t * rec, const record_t * rec2);
42 
43 	/* Same as above, but dereferences the pointer first.
44 	 * This function is intenteded to be used as a qsort
45 	 * comparator. */
46 	int (*compare2_qsort) (const record_t ** rec, const record_t ** rec2);
47 
48 	/* Deep-copy clone of this record */
49 	int (*clone) (struct semanage_handle * handle,
50 		      const record_t * rec, record_t ** new_rec);
51 
52 	/* Deallocate record resources. Must sucessfully handle NULL. */
53 	void (*free) (record_t * rec);
54 
55 } record_table_t;
56 
57 /* DBASE interface - method table */
58 typedef struct dbase_table {
59 
60 	/* --------------- Database Functionality ----------- */
61 
62 	/* Note: In all the functions below, the key is property
63 	 * of the caller, and will not be modified by the database.
64 	 * In add/set/modify, the data is also property of the caller */
65 
66 	/* Add the specified record to
67 	 * the database. No check for duplicates is performed */
68 	int (*add) (struct semanage_handle * handle,
69 		    dbase_t * dbase,
70 		    const record_key_t * key, const record_t * data);
71 
72 	/* Add the specified record to the
73 	 * database if it not present.
74 	 * If it's present, replace it
75 	 */
76 	int (*modify) (struct semanage_handle * handle,
77 		       dbase_t * dbase,
78 		       const record_key_t * key, const record_t * data);
79 
80 	/* Modify the specified record in the database
81 	 * if it is present. Fail if it does not yet exist
82 	 */
83 	int (*set) (struct semanage_handle * handle,
84 		    dbase_t * dbase,
85 		    const record_key_t * key, const record_t * data);
86 
87 	/* Delete a record */
88 	int (*del) (struct semanage_handle * handle,
89 		    dbase_t * dbase, const record_key_t * key);
90 
91 	/* Clear all records, and leave the database in
92 	 * cached, modified state. This function does
93 	 * not require a call to cache() */
94 	int (*clear) (struct semanage_handle * handle, dbase_t * dbase);
95 
96 	/* Retrieve a record
97 	 *
98 	 * Note: the resultant record
99 	 * becomes property of the caller, and
100 	 * must be freed accordingly */
101 
102 	int (*query) (struct semanage_handle * handle,
103 		      dbase_t * dbase,
104 		      const record_key_t * key, record_t ** response);
105 
106 	/* Check if a record exists */
107 	int (*exists) (struct semanage_handle * handle,
108 		       dbase_t * dbase,
109 		       const record_key_t * key, int *response);
110 
111 	/* Count the number of records */
112 	int (*count) (struct semanage_handle * handle,
113 		      dbase_t * dbase, unsigned int *response);
114 
115 	/* Execute the specified handler over
116 	 * the records of this database. The handler
117 	 * can signal a successful exit by returning 1,
118 	 * an error exit by returning -1, and continue by
119 	 * returning 0
120 	 *
121 	 * Note: The record passed into the iterate handler
122 	 * may or may not persist after the handler invocation,
123 	 * and writing to it has unspecified behavior. It *must*
124 	 * be cloned if modified, or preserved.
125 	 *
126 	 * Note: The iterate handler may not invoke any other
127 	 * semanage read functions outside a transaction. It is only
128 	 * reentrant while in transaction. The iterate handler may
129 	 * not modify the underlying database.
130 	 */
131 	int (*iterate) (struct semanage_handle * handle,
132 			dbase_t * dbase,
133 			int (*fn) (const record_t * record,
134 				   void *varg), void *fn_arg);
135 
136 	/* Construct a list of all records in this database
137 	 *
138 	 * Note: The list returned becomes property of the caller,
139 	 * and must be freed accordingly.
140 	 */
141 	int (*list) (struct semanage_handle * handle,
142 		     dbase_t * dbase,
143 		     record_t *** records, unsigned int *count);
144 
145 	/* ---------- Cache/Transaction Management ---------- */
146 
147 	/* Cache the database (if supported).
148 	 * This function must be invoked before using
149 	 * any of the database functions above. It may be invoked
150 	 * multiple times, and will update the cache if a commit
151 	 * occured between invocations */
152 	int (*cache) (struct semanage_handle * handle, dbase_t * dbase);
153 
154 	/* Forgets all changes that haven't been written
155 	 * to the database backend */
156 	void (*drop_cache) (dbase_t * dbase);
157 
158 	/* Checks if there are any changes not written to the backend */
159 	int (*is_modified) (dbase_t * dbase);
160 
161 	/* Writes the database changes to its backend */
162 	int (*flush) (struct semanage_handle * handle, dbase_t * dbase);
163 
164 	/* ------------- Polymorphism ----------------------- */
165 
166 	/* Retrieves the record table for this database,
167 	 * which specifies how to perform basic operations
168 	 * on each record. */
169 	record_table_t *(*get_rtable) (dbase_t * dbase);
170 
171 } dbase_table_t;
172 
173 typedef struct dbase_config {
174 
175 	/* Database state */
176 	dbase_t *dbase;
177 
178 	/* Database methods */
179 	dbase_table_t *dtable;
180 
181 } dbase_config_t;
182 
183 extern int dbase_add(struct semanage_handle *handle,
184 		     dbase_config_t * dconfig,
185 		     const record_key_t * key, const record_t * data);
186 
187 extern int dbase_modify(struct semanage_handle *handle,
188 			dbase_config_t * dconfig,
189 			const record_key_t * key, const record_t * data);
190 
191 extern int dbase_set(struct semanage_handle *handle,
192 		     dbase_config_t * dconfig,
193 		     const record_key_t * key, const record_t * data);
194 
195 extern int dbase_del(struct semanage_handle *handle,
196 		     dbase_config_t * dconfig, const record_key_t * key);
197 
198 extern int dbase_query(struct semanage_handle *handle,
199 		       dbase_config_t * dconfig,
200 		       const record_key_t * key, record_t ** response);
201 
202 extern int dbase_exists(struct semanage_handle *handle,
203 			dbase_config_t * dconfig,
204 			const record_key_t * key, int *response);
205 
206 extern int dbase_count(struct semanage_handle *handle,
207 		       dbase_config_t * dconfig, unsigned int *response);
208 
209 extern int dbase_iterate(struct semanage_handle *handle,
210 			 dbase_config_t * dconfig,
211 			 int (*fn) (const record_t * record,
212 				    void *fn_arg), void *fn_arg);
213 
214 extern int dbase_list(struct semanage_handle *handle,
215 		      dbase_config_t * dconfig,
216 		      record_t *** records, unsigned int *count);
217 
218 #endif
219