[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Support for dynamically loadable backends
The attached patch adds support for dynamic loading of HDB backends
on platforms that support it.
-- Luke
Index: hdb.c
===================================================================
RCS file: /home/project/cvs/heimdal/lib/hdb/hdb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -r1.1.1.1 -r1.6
--- hdb.c 2002/08/11 23:53:58 1.1.1.1
+++ hdb.c 2002/11/04 12:00:01 1.6
@@ -33,8 +33,12 @@
#include "hdb_locl.h"
-RCSID("$Id: hdb.c,v 1.1.1.1 2002/08/11 23:53:58 lukeh Exp $");
+RCSID("$Id: hdb.c,v 1.6 2002/11/04 12:00:01 lukeh Exp $");
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
struct hdb_method {
const char *prefix;
krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
@@ -205,7 +209,62 @@
return ret;
}
+#ifdef HAVE_DLOPEN
/*
+ * Load a dynamic backend from /usr/heimdal/lib/hdb_XXX.so,
+ * looking for the hdb_XXX_create symbol.
+ */
+static const struct hdb_method *
+find_dynamic_method (const char *filename, const char **rest)
+{
+ const char *p;
+ void *dl;
+ char path[MAXPATHLEN], symbol[128];
+ static struct hdb_method method;
+ size_t len;
+
+ if (method.prefix != NULL) {
+ free((char *)method.prefix);
+ }
+
+ p = strchr((char *)filename, ':');
+ if (p != NULL) {
+ len = p - filename;
+ *rest = filename + len + 1;
+ } else {
+ len = strlen(filename);
+ *rest = "";
+ }
+
+ method.prefix = malloc(len + 1);
+ if (method.prefix == NULL) {
+ return NULL;
+ }
+
+ memcpy((char *)method.prefix, filename, len);
+ ((char *)method.prefix)[len] = '\0';
+
+ snprintf(path, sizeof(path), LIBDIR "/hdb_%s.so", method.prefix);
+ snprintf(symbol, sizeof(symbol), "hdb_%s_create", method.prefix);
+
+ dl = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dl == NULL) {
+ fprintf(stderr, "error loading dynamic module %s: %s\n", path, dlerror());
+ return NULL;
+ }
+
+ method.create = dlsym(dl, symbol);
+ if (method.create == NULL) {
+ fprintf(stderr, "error finding symbol %s: %s\n", symbol, dlerror());
+ dlclose(dl);
+ return NULL;
+ }
+
+ return &method;
+}
+#endif /* HAVE_DLOPEN */
+
+/*
* find the relevant method for `filename', returning a pointer to the
* rest in `rest'.
* return NULL if there's no such method.
@@ -233,6 +292,10 @@
if(filename == NULL)
filename = HDB_DEFAULT_DB;
krb5_add_et_list(context, initialize_hdb_error_table_r);
+#ifdef HAVE_DLOPEN
+ h = find_dynamic_method (filename, &residual);
+ if (h == NULL)
+#endif
h = find_method (filename, &residual);
if (h == NULL)
krb5_errx(context, 1, "No database support! (hdb_create)");
--
Luke Howard | PADL Software Pty Ltd | www.padl.com