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 successfully 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 * occurred 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