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, see <https://www.gnu.org/licenses/>.
23 #include "decodekey.h"
27 #include "keystructs.h"
31 #include "onak-conf.h"
36 struct onak_dynamic_dbctx {
37 struct onak_dbctx *loadeddbctx;
41 static bool dynamic_starttrans(struct onak_dbctx *dbctx)
43 struct onak_dynamic_dbctx *privctx =
44 (struct onak_dynamic_dbctx *) dbctx->priv;
46 return privctx->loadeddbctx->starttrans(privctx->loadeddbctx);
49 static void dynamic_endtrans(struct onak_dbctx *dbctx)
51 struct onak_dynamic_dbctx *privctx =
52 (struct onak_dynamic_dbctx *) dbctx->priv;
54 privctx->loadeddbctx->endtrans(privctx->loadeddbctx);
57 static int dynamic_fetch_key(struct onak_dbctx *dbctx,
58 struct openpgp_fingerprint *fingerprint,
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(privctx->loadeddbctx,
65 fingerprint, publickey, intrans);
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 if (privctx->loadeddbctx->fetch_key_fp)
76 return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx,
77 fingerprint, publickey, intrans);
79 return privctx->loadeddbctx->fetch_key(privctx->loadeddbctx,
80 fingerprint, publickey, intrans);
83 static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
84 struct openpgp_publickey **publickey, bool intrans)
86 struct onak_dynamic_dbctx *privctx =
87 (struct onak_dynamic_dbctx *) dbctx->priv;
89 return privctx->loadeddbctx->fetch_key_id(privctx->loadeddbctx, keyid,
93 static int dynamic_fetch_key_text(struct onak_dbctx *dbctx,
95 struct openpgp_publickey **publickey)
97 struct onak_dynamic_dbctx *privctx =
98 (struct onak_dynamic_dbctx *) dbctx->priv;
100 return privctx->loadeddbctx->fetch_key_text(privctx->loadeddbctx,
104 static int dynamic_fetch_key_skshash(struct onak_dbctx *dbctx,
105 const struct skshash *hash,
106 struct openpgp_publickey **publickey)
108 struct onak_dynamic_dbctx *privctx =
109 (struct onak_dynamic_dbctx *) dbctx->priv;
111 return privctx->loadeddbctx->fetch_key_skshash(privctx->loadeddbctx,
115 static int dynamic_store_key(struct onak_dbctx *dbctx,
116 struct openpgp_publickey *publickey, bool intrans,
119 struct onak_dynamic_dbctx *privctx =
120 (struct onak_dynamic_dbctx *) dbctx->priv;
122 return privctx->loadeddbctx->store_key(privctx->loadeddbctx,
123 publickey, intrans, update);
126 static int dynamic_delete_key(struct onak_dbctx *dbctx,
127 struct openpgp_fingerprint *fp,
130 struct onak_dynamic_dbctx *privctx =
131 (struct onak_dynamic_dbctx *) dbctx->priv;
133 return privctx->loadeddbctx->delete_key(privctx->loadeddbctx,
137 static int dynamic_update_keys(struct onak_dbctx *dbctx,
138 struct openpgp_publickey **keys,
139 struct keyarray *blacklist,
143 struct onak_dynamic_dbctx *privctx =
144 (struct onak_dynamic_dbctx *) dbctx->priv;
146 return privctx->loadeddbctx->update_keys(privctx->loadeddbctx,
147 keys, blacklist, updateonly, sendsync);
150 static struct ll *dynamic_getkeysigs(struct onak_dbctx *dbctx,
151 uint64_t keyid, bool *revoked)
153 struct onak_dynamic_dbctx *privctx =
154 (struct onak_dynamic_dbctx *) dbctx->priv;
156 return privctx->loadeddbctx->getkeysigs(privctx->loadeddbctx,
160 static struct ll *dynamic_cached_getkeysigs(struct onak_dbctx *dbctx,
163 struct onak_dynamic_dbctx *privctx =
164 (struct onak_dynamic_dbctx *) dbctx->priv;
166 return privctx->loadeddbctx->cached_getkeysigs(privctx->loadeddbctx,
170 static char *dynamic_keyid2uid(struct onak_dbctx *dbctx,
173 struct onak_dynamic_dbctx *privctx =
174 (struct onak_dynamic_dbctx *) dbctx->priv;
176 return privctx->loadeddbctx->keyid2uid(privctx->loadeddbctx,
180 static int dynamic_iterate_keys(struct onak_dbctx *dbctx,
181 void (*iterfunc)(void *ctx, struct openpgp_publickey *key),
184 struct onak_dynamic_dbctx *privctx =
185 (struct onak_dynamic_dbctx *) dbctx->priv;
187 return privctx->loadeddbctx->iterate_keys(privctx->loadeddbctx,
191 static void dynamic_cleanupdb(struct onak_dbctx *dbctx)
193 struct onak_dynamic_dbctx *privctx =
194 (struct onak_dynamic_dbctx *) dbctx->priv;
196 if (privctx->loadeddbctx != NULL) {
197 if (privctx->loadeddbctx->cleanupdb != NULL) {
198 privctx->loadeddbctx->cleanupdb(privctx->loadeddbctx);
199 privctx->loadeddbctx = NULL;
203 if (privctx->backend_handle != NULL) {
204 dlclose(privctx->backend_handle);
205 privctx->backend_handle = NULL;
208 if (dbctx->priv != NULL) {
218 struct onak_dbctx *keydb_dynamic_init(struct onak_db_config *dbcfg,
221 struct onak_dbctx *dbctx;
224 struct onak_dbctx *(*backend_init)(struct onak_db_config *, bool);
225 struct onak_dynamic_dbctx *privctx;
229 logthing(LOGTHING_CRITICAL,
230 "No backend database configuration supplied.");
234 dbctx = malloc(sizeof(struct onak_dbctx));
240 dbctx->config = dbcfg;
241 dbctx->priv = privctx = malloc(sizeof(struct onak_dynamic_dbctx));
242 if (dbctx->priv == NULL) {
248 if (config.use_keyd) {
252 if (!config.db_backend) {
253 logthing(LOGTHING_CRITICAL, "No database backend defined.");
257 if (config.backends_dir == NULL) {
258 soname = malloc(strlen(type)
259 + strlen("./libkeydb_")
263 sprintf(soname, "./libkeydb_%s.so", type);
265 soname = malloc(strlen(type)
266 + strlen("/libkeydb_")
268 + strlen(config.backends_dir)
271 sprintf(soname, "%s/libkeydb_%s.so", config.backends_dir,
275 logthing(LOGTHING_INFO, "Loading dynamic backend: %s", soname);
277 privctx->backend_handle = dlopen(soname, RTLD_LAZY);
278 if (privctx->backend_handle == NULL) {
279 logthing(LOGTHING_CRITICAL,
280 "Failed to open handle to library '%s': %s",
287 initname = malloc(strlen(config.db_backend)
291 sprintf(initname, "keydb_%s_init", type);
293 *(void **) (&backend_init) = dlsym(privctx->backend_handle, initname);
296 if (backend_init == NULL) {
297 logthing(LOGTHING_CRITICAL,
298 "Failed to find dbfuncs structure in library "
299 "'%s' : %s", soname, dlerror());
305 privctx->loadeddbctx = backend_init(dbcfg, readonly);
307 if (privctx->loadeddbctx == NULL) {
308 logthing(LOGTHING_CRITICAL,
309 "Failed to initialise dynamic backend: %s",
318 if (privctx->loadeddbctx != NULL) {
319 dbctx->cleanupdb = dynamic_cleanupdb;
320 dbctx->starttrans = dynamic_starttrans;
321 dbctx->endtrans = dynamic_endtrans;
322 dbctx->fetch_key = dynamic_fetch_key;
323 dbctx->fetch_key_fp = dynamic_fetch_key_fp;
324 dbctx->fetch_key_id = dynamic_fetch_key_id;
325 dbctx->fetch_key_text = dynamic_fetch_key_text;
326 dbctx->fetch_key_skshash = dynamic_fetch_key_skshash;
327 dbctx->store_key = dynamic_store_key;
328 dbctx->update_keys = dynamic_update_keys;
329 dbctx->delete_key = dynamic_delete_key;
330 dbctx->getkeysigs = dynamic_getkeysigs;
331 dbctx->cached_getkeysigs = dynamic_cached_getkeysigs;
332 dbctx->keyid2uid = dynamic_keyid2uid;
333 dbctx->iterate_keys = dynamic_iterate_keys;