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 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 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 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 */ 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