[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Support for dynamically loadable backends
Luke Howard <lukeh@PADL.COM> writes:
> Upon reviewing this I realised it's preferable to use krb5_errx()
> than fprintf(). See revised patch (attached).
Wont loading of non-dynamic modules fail then ? I think warnx is what you
want.
it the (untested) patch below ok with you ?
Love
Index: hdb.c
===================================================================
RCS file: /afs/pdc.kth.se/src/packages/kth-krb/SourceRepository/heimdal/lib/hdb/hdb.c,v
retrieving revision 1.44
diff -u -u -w -r1.44 hdb.c
--- hdb.c 9 Aug 2001 08:41:48 -0000 1.44
+++ hdb.c 26 Jun 2003 04:10:58 -0000
@@ -35,6 +35,10 @@
RCSID("$Id: hdb.c,v 1.44 2001/08/09 08:41:48 assar 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,6 +210,72 @@
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 (krb5_context context,
+ const char *filename,
+ const char **rest)
+{
+ static struct hdb_method method;
+ char *prefix, *path, *symbol;
+ const char *p;
+ void *dl;
+ size_t len;
+
+ dl = NULL;
+
+ p = strchr(filename, ':');
+ if (p != NULL) {
+ len = p - filename;
+ *rest = filename + len + 1;
+ } else {
+ len = strlen(filename);
+ *rest = "";
+ }
+
+ prefix = strndup(filename, len);
+ if (prefix == NULL)
+ krb5_errx(context, 1, "out of memory");
+
+ if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1)
+ krb5_errx(context, 1, "out of memory");
+
+ dl = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dl == NULL) {
+ krb5_warnx(context, "error trying to load dynamic module %s: %s\n",
+ path, dlerror());
+ free(prefix);
+ free(path);
+ return NULL;
+ }
+ free(path);
+
+ if (asprintf(&symbol, "hdb_%s_create", prefix) == -1)
+ krb5_errx(context, 1, "out of memory");
+
+ method.create = dlsym(dl, symbol);
+ if (method.create == NULL) {
+ krb5_warnx(context, "error finding symbol %s: %s\n",
+ symbol, dlerror());
+ dlclose(dl);
+ free(symbol);
+ free(prefix);
+ return NULL;
+ }
+ free(symbol);
+
+ method.prefix = prefix;
+
+ return &method;
+}
+#endif /* HAVE_DLOPEN */
+
/*
* find the relevant method for `filename', returning a pointer to the
* rest in `rest'.
@@ -227,12 +298,16 @@
krb5_error_code
hdb_create(krb5_context context, HDB **db, const char *filename)
{
- const struct hdb_method *h;
+ const struct hdb_method *h = NULL;
const char *residual;
if(filename == NULL)
filename = HDB_DEFAULT_DB;
krb5_add_et_list(context, initialize_hdb_error_table_r);
+#ifdef HAVE_DLOPEN
+ h = find_dynamic_method (context, filename, &residual);
+#endif
+ if (h == NULL)
h = find_method (filename, &residual);
if (h == NULL)
krb5_errx(context, 1, "No database support! (hdb_create)");
PGP signature