X-Git-Url: https://the.earth.li/gitweb/?a=blobdiff_plain;f=keydb%2Fkeydb_dynamic.c;fp=keydb%2Fkeydb_dynamic.c;h=385c09cbb5ef3600e2b9e9a59a79b61d423f4c03;hb=51c1a7dd950efef6a4d00df1878341777f8064ff;hp=0000000000000000000000000000000000000000;hpb=dfab9e96ee1fa4a10acf9c1cf644d7a4366a5af6;p=onak.git diff --git a/keydb/keydb_dynamic.c b/keydb/keydb_dynamic.c new file mode 100644 index 0000000..385c09c --- /dev/null +++ b/keydb/keydb_dynamic.c @@ -0,0 +1,321 @@ +/* + * keydb_dynamic.c - backend that can load the other backends + * + * Copyright 2005 Brett Parker + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include + +#include "decodekey.h" +#include "hash.h" +#include "keydb.h" +#include "keyid.h" +#include "keystructs.h" +#include "log.h" +#include "mem.h" +#include "merge.h" +#include "onak-conf.h" +#include "openpgp.h" +#include "parsekey.h" +#include "sendsync.h" + +struct onak_dynamic_dbctx { + struct onak_dbctx *loadeddbctx; + void *backend_handle; +}; + +static bool dynamic_starttrans(struct onak_dbctx *dbctx) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->starttrans(privctx->loadeddbctx); +} + +static void dynamic_endtrans(struct onak_dbctx *dbctx) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + privctx->loadeddbctx->endtrans(privctx->loadeddbctx); +} + +static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid, + struct openpgp_publickey **publickey, bool intrans) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->fetch_key_id(privctx->loadeddbctx, keyid, + publickey, intrans); +} + +static int dynamic_fetch_key_fp(struct onak_dbctx *dbctx, + struct openpgp_fingerprint *fingerprint, + struct openpgp_publickey **publickey, bool intrans) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx, + fingerprint, publickey, intrans); +} + +static int dynamic_fetch_key_text(struct onak_dbctx *dbctx, + const char *search, + struct openpgp_publickey **publickey) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->fetch_key_text(privctx->loadeddbctx, + search, publickey); +} + +static int dynamic_fetch_key_skshash(struct onak_dbctx *dbctx, + const struct skshash *hash, + struct openpgp_publickey **publickey) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->fetch_key_skshash(privctx->loadeddbctx, + hash, publickey); +} + +static int dynamic_store_key(struct onak_dbctx *dbctx, + struct openpgp_publickey *publickey, bool intrans, + bool update) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->store_key(privctx->loadeddbctx, + publickey, intrans, update); +} + +static int dynamic_delete_key(struct onak_dbctx *dbctx, + struct openpgp_fingerprint *fp, + bool intrans) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->delete_key(privctx->loadeddbctx, + fp, intrans); +} + +static int dynamic_update_keys(struct onak_dbctx *dbctx, + struct openpgp_publickey **keys, + struct keyarray *blacklist, + bool updateonly, + bool sendsync) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->update_keys(privctx->loadeddbctx, + keys, blacklist, updateonly, sendsync); +} + +static struct ll *dynamic_getkeysigs(struct onak_dbctx *dbctx, + uint64_t keyid, bool *revoked) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->getkeysigs(privctx->loadeddbctx, + keyid, revoked); +} + +static struct ll *dynamic_cached_getkeysigs(struct onak_dbctx *dbctx, + uint64_t keyid) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->cached_getkeysigs(privctx->loadeddbctx, + keyid); +} + +static char *dynamic_keyid2uid(struct onak_dbctx *dbctx, + uint64_t keyid) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->keyid2uid(privctx->loadeddbctx, + keyid); +} + +static int dynamic_iterate_keys(struct onak_dbctx *dbctx, + void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + return privctx->loadeddbctx->iterate_keys(privctx->loadeddbctx, + iterfunc, ctx); +} + +static void dynamic_cleanupdb(struct onak_dbctx *dbctx) +{ + struct onak_dynamic_dbctx *privctx = + (struct onak_dynamic_dbctx *) dbctx->priv; + + if (privctx->loadeddbctx != NULL) { + if (privctx->loadeddbctx->cleanupdb != NULL) { + privctx->loadeddbctx->cleanupdb(privctx->loadeddbctx); + privctx->loadeddbctx = NULL; + } + } + + if (privctx->backend_handle != NULL) { + dlclose(privctx->backend_handle); + privctx->backend_handle = NULL; + } + + if (dbctx->priv != NULL) { + free(dbctx->priv); + dbctx->priv = NULL; + } + + if (dbctx != NULL) { + free(dbctx); + } +} + +struct onak_dbctx *keydb_dynamic_init(struct onak_db_config *dbcfg, + bool readonly) +{ + struct onak_dbctx *dbctx; + char *soname; + char *initname; + struct onak_dbctx *(*backend_init)(struct onak_db_config *, bool); + struct onak_dynamic_dbctx *privctx; + char *type; + + if (dbcfg == NULL) { + logthing(LOGTHING_CRITICAL, + "No backend database configuration supplied."); + return NULL; + } + + dbctx = malloc(sizeof(struct onak_dbctx)); + + if (dbctx == NULL) { + return NULL; + } + + dbctx->config = dbcfg; + dbctx->priv = privctx = malloc(sizeof(struct onak_dynamic_dbctx)); + if (dbctx->priv == NULL) { + free(dbctx); + return (NULL); + } + + type = dbcfg->type; + if (config.use_keyd) { + type = "keyd"; + } + + if (!config.db_backend) { + logthing(LOGTHING_CRITICAL, "No database backend defined."); + exit(EXIT_FAILURE); + } + + if (config.backends_dir == NULL) { + soname = malloc(strlen(type) + + strlen("./libkeydb_") + + strlen(".so") + + 1); + + sprintf(soname, "./libkeydb_%s.so", type); + } else { + soname = malloc(strlen(type) + + strlen("/libkeydb_") + + strlen(".so") + + strlen(config.backends_dir) + + 1); + + sprintf(soname, "%s/libkeydb_%s.so", config.backends_dir, + type); + } + + logthing(LOGTHING_INFO, "Loading dynamic backend: %s", soname); + + privctx->backend_handle = dlopen(soname, RTLD_LAZY); + if (privctx->backend_handle == NULL) { + logthing(LOGTHING_CRITICAL, + "Failed to open handle to library '%s': %s", + soname, dlerror()); + free(soname); + soname = NULL; + exit(EXIT_FAILURE); + } + + initname = malloc(strlen(config.db_backend) + + strlen("keydb_") + + strlen("_init") + + 1); + sprintf(initname, "keydb_%s_init", type); + + *(void **) (&backend_init) = dlsym(privctx->backend_handle, initname); + free(initname); + + if (backend_init == NULL) { + logthing(LOGTHING_CRITICAL, + "Failed to find dbfuncs structure in library " + "'%s' : %s", soname, dlerror()); + free(soname); + soname = NULL; + exit(EXIT_FAILURE); + } + + privctx->loadeddbctx = backend_init(dbcfg, readonly); + + if (privctx->loadeddbctx == NULL) { + logthing(LOGTHING_CRITICAL, + "Failed to initialise dynamic backend: %s", + soname); + free(soname); + soname = NULL; + exit(EXIT_FAILURE); + } + free(soname); + soname = NULL; + + if (privctx->loadeddbctx != NULL) { + dbctx->cleanupdb = dynamic_cleanupdb; + dbctx->starttrans = dynamic_starttrans; + dbctx->endtrans = dynamic_endtrans; + dbctx->fetch_key_id = dynamic_fetch_key_id; + dbctx->fetch_key_fp = dynamic_fetch_key_fp; + dbctx->fetch_key_text = dynamic_fetch_key_text; + dbctx->fetch_key_skshash = dynamic_fetch_key_skshash; + dbctx->store_key = dynamic_store_key; + dbctx->update_keys = dynamic_update_keys; + dbctx->delete_key = dynamic_delete_key; + dbctx->getkeysigs = dynamic_getkeysigs; + dbctx->cached_getkeysigs = dynamic_cached_getkeysigs; + dbctx->keyid2uid = dynamic_keyid2uid; + dbctx->iterate_keys = dynamic_iterate_keys; + } + + return dbctx; +}