2 * keydb_dynamic.c - backend that can load the other backends
4 * Copyright 2005 Brett Parker <iDunno@sommitrealweird.co.uk>
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "decodekey.h"
28 #include "keystructs.h"
32 #include "onak-conf.h"
37 struct onak_dynamic_dbctx {
38 struct onak_dbctx *loadeddbctx;
42 static bool dynamic_starttrans(struct onak_dbctx *dbctx)
44 struct onak_dynamic_dbctx *privctx =
45 (struct onak_dynamic_dbctx *) dbctx->priv;
47 return privctx->loadeddbctx->starttrans(privctx->loadeddbctx);
50 static void dynamic_endtrans(struct onak_dbctx *dbctx)
52 struct onak_dynamic_dbctx *privctx =
53 (struct onak_dynamic_dbctx *) dbctx->priv;
55 privctx->loadeddbctx->endtrans(privctx->loadeddbctx);
58 static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
59 struct openpgp_publickey **publickey, bool intrans)
61 struct onak_dynamic_dbctx *privctx =
62 (struct onak_dynamic_dbctx *) dbctx->priv;
64 return privctx->loadeddbctx->fetch_key_id(privctx->loadeddbctx, keyid,
68 static int dynamic_fetch_key_fp(struct onak_dbctx *dbctx,
69 struct openpgp_fingerprint *fingerprint,
70 struct openpgp_publickey **publickey, bool intrans)
72 struct onak_dynamic_dbctx *privctx =
73 (struct onak_dynamic_dbctx *) dbctx->priv;
75 return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx,
76 fingerprint, publickey, intrans);
79 static int dynamic_fetch_key_text(struct onak_dbctx *dbctx,
81 struct openpgp_publickey **publickey)
83 struct onak_dynamic_dbctx *privctx =
84 (struct onak_dynamic_dbctx *) dbctx->priv;
86 return privctx->loadeddbctx->fetch_key_text(privctx->loadeddbctx,
90 static int dynamic_fetch_key_skshash(struct onak_dbctx *dbctx,
91 const struct skshash *hash,
92 struct openpgp_publickey **publickey)
94 struct onak_dynamic_dbctx *privctx =
95 (struct onak_dynamic_dbctx *) dbctx->priv;
97 return privctx->loadeddbctx->fetch_key_skshash(privctx->loadeddbctx,
101 static int dynamic_store_key(struct onak_dbctx *dbctx,
102 struct openpgp_publickey *publickey, bool intrans,
105 struct onak_dynamic_dbctx *privctx =
106 (struct onak_dynamic_dbctx *) dbctx->priv;
108 return privctx->loadeddbctx->store_key(privctx->loadeddbctx,
109 publickey, intrans, update);
112 static int dynamic_delete_key(struct onak_dbctx *dbctx, uint64_t keyid,
115 struct onak_dynamic_dbctx *privctx =
116 (struct onak_dynamic_dbctx *) dbctx->priv;
118 return privctx->loadeddbctx->delete_key(privctx->loadeddbctx,
122 static int dynamic_update_keys(struct onak_dbctx *dbctx,
123 struct openpgp_publickey **keys, bool sendsync)
125 struct onak_dynamic_dbctx *privctx =
126 (struct onak_dynamic_dbctx *) dbctx->priv;
128 return privctx->loadeddbctx->update_keys(privctx->loadeddbctx,
132 static struct ll *dynamic_getkeysigs(struct onak_dbctx *dbctx,
133 uint64_t keyid, bool *revoked)
135 struct onak_dynamic_dbctx *privctx =
136 (struct onak_dynamic_dbctx *) dbctx->priv;
138 return privctx->loadeddbctx->getkeysigs(privctx->loadeddbctx,
142 static struct ll *dynamic_cached_getkeysigs(struct onak_dbctx *dbctx,
145 struct onak_dynamic_dbctx *privctx =
146 (struct onak_dynamic_dbctx *) dbctx->priv;
148 return privctx->loadeddbctx->cached_getkeysigs(privctx->loadeddbctx,
152 static char *dynamic_keyid2uid(struct onak_dbctx *dbctx,
155 struct onak_dynamic_dbctx *privctx =
156 (struct onak_dynamic_dbctx *) dbctx->priv;
158 return privctx->loadeddbctx->keyid2uid(privctx->loadeddbctx,
162 static uint64_t dynamic_getfullkeyid(struct onak_dbctx *dbctx,
165 struct onak_dynamic_dbctx *privctx =
166 (struct onak_dynamic_dbctx *) dbctx->priv;
168 return privctx->loadeddbctx->getfullkeyid(privctx->loadeddbctx, keyid);
171 static int dynamic_iterate_keys(struct onak_dbctx *dbctx,
172 void (*iterfunc)(void *ctx, struct openpgp_publickey *key),
175 struct onak_dynamic_dbctx *privctx =
176 (struct onak_dynamic_dbctx *) dbctx->priv;
178 return privctx->loadeddbctx->iterate_keys(privctx->loadeddbctx,
182 static void dynamic_cleanupdb(struct onak_dbctx *dbctx)
184 struct onak_dynamic_dbctx *privctx =
185 (struct onak_dynamic_dbctx *) dbctx->priv;
187 if (privctx->loadeddbctx != NULL) {
188 if (privctx->loadeddbctx->cleanupdb != NULL) {
189 privctx->loadeddbctx->cleanupdb(privctx->loadeddbctx);
190 privctx->loadeddbctx = NULL;
194 if (privctx->backend_handle != NULL) {
195 dlclose(privctx->backend_handle);
196 privctx->backend_handle = NULL;
199 if (dbctx->priv != NULL) {
209 struct onak_dbctx *keydb_dynamic_init(bool readonly)
211 struct onak_dbctx *dbctx;
214 struct onak_dbctx *(*backend_init)(bool);
215 struct onak_dynamic_dbctx *privctx;
217 dbctx = malloc(sizeof(struct onak_dbctx));
223 dbctx->priv = privctx = malloc(sizeof(struct onak_dynamic_dbctx));
224 if (dbctx->priv == NULL) {
229 if (config.use_keyd) {
230 free(config.db_backend);
231 config.db_backend = strdup("keyd");
234 if (!config.db_backend) {
235 logthing(LOGTHING_CRITICAL, "No database backend defined.");
239 if (config.backends_dir == NULL) {
240 soname = malloc(strlen(config.db_backend)
241 + strlen("./libkeydb_")
245 sprintf(soname, "./libkeydb_%s.so", config.db_backend);
247 soname = malloc(strlen(config.db_backend)
248 + strlen("/libkeydb_")
250 + strlen(config.backends_dir)
253 sprintf(soname, "%s/libkeydb_%s.so", config.backends_dir,
257 logthing(LOGTHING_INFO, "Loading dynamic backend: %s", soname);
259 privctx->backend_handle = dlopen(soname, RTLD_LAZY);
260 if (privctx->backend_handle == NULL) {
261 logthing(LOGTHING_CRITICAL,
262 "Failed to open handle to library '%s': %s",
269 initname = malloc(strlen(config.db_backend)
273 sprintf(initname, "keydb_%s_init", config.db_backend);
275 *(void **) (&backend_init) = dlsym(privctx->backend_handle, initname);
278 if (backend_init == NULL) {
279 logthing(LOGTHING_CRITICAL,
280 "Failed to find dbfuncs structure in library "
281 "'%s' : %s", soname, dlerror());
289 privctx->loadeddbctx = backend_init(readonly);
291 if (privctx->loadeddbctx != NULL) {
292 dbctx->cleanupdb = dynamic_cleanupdb;
293 dbctx->starttrans = dynamic_starttrans;
294 dbctx->endtrans = dynamic_endtrans;
295 dbctx->fetch_key_id = dynamic_fetch_key_id;
296 dbctx->fetch_key_fp = dynamic_fetch_key_fp;
297 dbctx->fetch_key_text = dynamic_fetch_key_text;
298 dbctx->fetch_key_skshash = dynamic_fetch_key_skshash;
299 dbctx->store_key = dynamic_store_key;
300 dbctx->update_keys = dynamic_update_keys;
301 dbctx->delete_key = dynamic_delete_key;
302 dbctx->getkeysigs = dynamic_getkeysigs;
303 dbctx->cached_getkeysigs = dynamic_cached_getkeysigs;
304 dbctx->keyid2uid = dynamic_keyid2uid;
305 dbctx->getfullkeyid = dynamic_getfullkeyid;
306 dbctx->iterate_keys = dynamic_iterate_keys;