summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2006-03-07 20:45:24 +0000
committerKen Raeburn <raeburn@mit.edu>2006-03-07 20:45:24 +0000
commit8f09bfe9fa0e51c2bd1e2f533eb25655e88ca43b (patch)
tree68c4097fc6650d9d2952fdc0b242263b60ae7f95 /src/util
parentca39d95f3cb9681664d3761f4c0c2ec23d36dfd3 (diff)
downloadkrb5-8f09bfe9fa0e51c2bd1e2f533eb25655e88ca43b.tar.gz
krb5-8f09bfe9fa0e51c2bd1e2f533eb25655e88ca43b.tar.xz
krb5-8f09bfe9fa0e51c2bd1e2f533eb25655e88ca43b.zip
Merge from plugin branch
Add plugin support: - plugin routines in support library (may break windows build!) - plugin support in KDC location code - sample Python-based plugin for KDC location, not built without tweaking sources - changed service location interface to use an enum instead of passing profile string and DNS strings and port numbers - changed pathnames for plugin locations, including kdb back end - remove locate_service from accessor API Also, do build shared libraries for Darwin just like any other UNIX box. Not present yet: - use new plugin interface for kdb back end - Windows support - Mac bundle support (but dlopen support works) - search path for libkrb5 plugins (only one hard-coded directory for now) - sorting of plugin collections for predictable ordering See the various ChangeLogs for specifics. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17706 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util')
-rw-r--r--src/util/profile/ChangeLog4
-rw-r--r--src/util/profile/Makefile.in2
-rw-r--r--src/util/support/ChangeLog8
-rw-r--r--src/util/support/Makefile.in6
-rw-r--r--src/util/support/libkrb5support.exports10
-rw-r--r--src/util/support/plugins.c339
6 files changed, 366 insertions, 3 deletions
diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog
index cbb95706e..ea269e8e2 100644
--- a/src/util/profile/ChangeLog
+++ b/src/util/profile/ChangeLog
@@ -1,3 +1,7 @@
+2006-03-06 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (profile_tcl): Include $(LIBS).
+
2005-10-21 Ken Raeburn <raeburn@mit.edu>
* prof_file.c (profile_update_file_data): Drop test of
diff --git a/src/util/profile/Makefile.in b/src/util/profile/Makefile.in
index 067007d84..a2d4814c8 100644
--- a/src/util/profile/Makefile.in
+++ b/src/util/profile/Makefile.in
@@ -119,7 +119,7 @@ profile_tcl.o: $(srcdir)/profile_tcl.c profile.h
profile_tcl: profile_tcl.o libprofile.a
$(CC_LINK) -o profile_tcl profile_tcl.o \
$(TCL_MAYBE_RPATH) \
- -L../et -L../.. libprofile.a $(DEPLIBS) $(TCL_LIBS)
+ -L../et -L../.. libprofile.a $(DEPLIBS) $(TCL_LIBS) $(LIBS)
clean-unix:: clean-libs clean-libobjs
$(RM) $(PROGS) *.o *~ test_parse core prof_err.h \
diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog
index 7c3c3648e..4ec482f24 100644
--- a/src/util/support/ChangeLog
+++ b/src/util/support/ChangeLog
@@ -1,3 +1,11 @@
+2006-03-06 Ken Raeburn <raeburn@mit.edu>
+
+ * plugins.c: New file.
+ * Makefile.in (LIBMAJOR): Update to 1.
+ (STLIBOBJS, LIBOBJS): Add new file.
+ (SHLIB_EXPLIBS): Add $(DL_LIB).
+ * libkrb5support.exports: Add new functions.
+
2006-02-24 Jeffrey Altman <jaltman@mit.edu>
* Makefile.in: support for 64-bit Windows builds
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index 5abd3a27e..da71cad88 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -18,7 +18,7 @@ PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
LIBBASE=krb5support
-LIBMAJOR=0
+LIBMAJOR=1
LIBMINOR=0
LIBINITFUNC=krb5int_thread_support_init
@@ -27,11 +27,13 @@ LIBFINIFUNC=krb5int_thread_support_fini
STLIBOBJS= \
threads.o \
init-addrinfo.o \
+ plugins.o \
fake-addrinfo.o
LIBOBJS= \
$(OUTPRE)threads.$(OBJEXT) \
$(OUTPRE)init-addrinfo.$(OBJEXT) \
+ $(OUTPRE)plugins.$(OBJEXT) \
$(OUTPRE)fake-addrinfo.$(OBJEXT)
STOBJLISTS=OBJS.ST
@@ -46,7 +48,7 @@ SRCS=\
$(srcdir)/fake-addrinfo.c
SHLIB_EXPDEPS =
# Add -lm if dumping thread stats, for sqrt.
-SHLIB_EXPLIBS= $(LIBS)
+SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
SHLIB_DIRS=
SHLIB_RDIRS=$(KRB5_LIBDIR)
diff --git a/src/util/support/libkrb5support.exports b/src/util/support/libkrb5support.exports
index d06911d53..1d7bc717f 100644
--- a/src/util/support/libkrb5support.exports
+++ b/src/util/support/libkrb5support.exports
@@ -11,6 +11,16 @@ krb5int_gai_strerror
krb5int_getnameinfo
krb5int_in6addr_any
krb5int_pthread_loaded
+krb5int_open_plugin
+krb5int_close_plugin
+krb5int_get_plugin_data
+krb5int_get_plugin_func
+krb5int_open_plugin_dir
+krb5int_close_plugin_dir
+krb5int_get_plugin_dir_data
+krb5int_get_plugin_dir_func
+krb5int_free_plugin_dir_data
+krb5int_free_plugin_dir_func
krb5int_mutex_alloc
krb5int_mutex_free
krb5int_mutex_lock
diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c
new file mode 100644
index 000000000..bc93aa2b4
--- /dev/null
+++ b/src/util/support/plugins.c
@@ -0,0 +1,339 @@
+/*
+ * util/support/plugins.c
+ *
+ * Copyright 2006 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Plugin module support, and shims around dlopen/whatever.
+ */
+
+#include "k5-int.h"
+#include <dlfcn.h>
+
+#include <stdarg.h>
+static void Tprintf (const char *fmt, ...)
+{
+#ifdef DEBUG
+ va_list va;
+ va_start (va, fmt);
+ vfprintf (stderr, fmt, va);
+ va_end (va);
+#endif
+}
+
+struct plugin_file_handle {
+#if 1
+ void *dlhandle;
+#define NULL_HANDLE(X) ((X)->dlhandle == NULL)
+#define MAKE_NULL_HANDLE(X) ((X)->dlhandle = NULL)
+/* #elif _WIN32 ... */
+#else
+ char dummy;
+#define NULL_HANDLE(X) (1)
+#define MAKE_NULL_HANDLE(X) (0)
+#endif
+};
+
+krb5_error_code KRB5_CALLCONV
+krb5int_open_plugin (const char *filename, struct plugin_file_handle **h)
+{
+ struct plugin_file_handle *htmp;
+ void *handle;
+
+ handle = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
+ if (handle == NULL) {
+ const char *e;
+ e = dlerror();
+ /* XXX copy and save away */
+ return ENOENT; /* XXX */
+ }
+ htmp = malloc (sizeof (*htmp));
+ if (htmp == NULL) {
+ int err = errno;
+ dlclose(handle);
+ return err;
+ }
+ *h = htmp;
+ htmp->dlhandle = handle;
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5int_get_plugin_data (struct plugin_file_handle *h, const char *csymname,
+ void **ptr)
+{
+ void *sym;
+ /* XXX Do we need to add a leading "_" to the symbol name on any
+ modern platforms? */
+ sym = dlsym(h->dlhandle, csymname);
+ if (sym == NULL) {
+ const char *e;
+ e = dlerror();
+ return ENOENT;
+ }
+ *ptr = sym;
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5int_get_plugin_func (struct plugin_file_handle *h, const char *csymname,
+ void (**ptr)())
+{
+ /* This code should do for any systems where function and data
+ symbols are handled the same. Note that this means there's no
+ function version of (say) dlsym, *and* the symbol-prefix
+ handling is the same for both data and functions. (And the
+ casting we do here works, etc.) */
+ void *dptr;
+ krb5_error_code err;
+
+ err = krb5int_get_plugin_data (h, csymname, &dptr);
+ if (err == 0)
+ *ptr = (void (*)()) dptr;
+ return err;
+}
+
+void KRB5_CALLCONV
+krb5int_close_plugin (struct plugin_file_handle *h)
+{
+ dlclose(h->dlhandle);
+ h->dlhandle = NULL;
+ free (h);
+}
+
+/* autoconf docs suggest using this preference order */
+#if HAVE_DIRENT_H || USE_DIRENT_H
+#include <dirent.h>
+#define NAMELEN(D) strlen((D)->d_name)
+#else
+#define dirent direct
+#define NAMELEN(D) ((D)->d->namlen)
+#if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+#elif HAVE_SYS_DIR_H
+# include <sys/dir.h>
+#elif HAVE_NDIR_H
+# include <ndir.h>
+#endif
+#endif
+
+krb5_error_code KRB5_CALLCONV
+krb5int_open_plugin_dir (const char *dirname,
+ struct plugin_dir_handle *dirhandle)
+{
+ /* Q: Should names be sorted in some way first? */
+ DIR *dir;
+ struct dirent *d;
+ struct plugin_file_handle *h, *newh, handle;
+ int nh;
+ int error = 0;
+ char path[MAXPATHLEN];
+
+ h = NULL;
+ nh = 0;
+ Tprintf("opening plugin directory '%s' to scan...\n", dirname);
+ dir = opendir(dirname);
+ if (dir == NULL) {
+ error = errno;
+ Tprintf("-> error %d/%s\n", error, strerror(error));
+ if (error == ENOENT)
+ return 0;
+ return error;
+ }
+ do {
+ size_t len;
+ struct stat statbuf;
+
+ d = readdir (dir);
+ if (d == NULL)
+ break;
+ len = NAMELEN(d);
+ if (strlen(dirname) + len + 2 > sizeof(path))
+ continue;
+ sprintf(path, "%s/%*s", dirname, (int) len, d->d_name);
+ /* Optimization: Linux includes a file type field in the
+ directory structure. */
+ if (stat(path, &statbuf) < 0) {
+ Tprintf("stat(%s): %s\n", path, strerror(errno));
+ continue;
+ }
+ if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
+ Tprintf("stat(%s): not a regular file\n", path);
+ continue;
+ }
+ Tprintf("trying to dlopen '%s'\n", path);
+ handle.dlhandle = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (handle.dlhandle == NULL) {
+ const char *e = dlerror();
+ Tprintf("dlopen error: %s\n", e);
+ /* dlerror(); */
+ continue;
+ } else {
+ Tprintf("dlopen succeeds: %p\n", handle.dlhandle);
+ }
+ newh = realloc (h, (nh+1) * sizeof(*h));
+ if (newh == NULL) {
+ int i;
+ close_and_return_errno:
+ error = errno;
+ for (i = 0; i < nh; i++)
+ dlclose(h[i].dlhandle);
+ free(h);
+ return error;
+ }
+ h = newh;
+ h[nh] = handle;
+ nh++;
+ } while (1);
+ Tprintf("done scanning plugin directory\n");
+ newh = realloc (h, (nh+1) * sizeof(*h));
+ if (newh == NULL)
+ goto close_and_return_errno;
+ h = newh;
+ MAKE_NULL_HANDLE (&h[nh]);
+ dirhandle->files = h;
+ return 0;
+}
+
+void KRB5_CALLCONV
+krb5int_close_plugin_dir (struct plugin_dir_handle *dirhandle)
+{
+ struct plugin_file_handle *h;
+ if (dirhandle->files == NULL)
+ return;
+ for (h = dirhandle->files; !NULL_HANDLE (h); h++) {
+ dlclose (h->dlhandle);
+ }
+ free(dirhandle->files);
+ dirhandle->files = NULL;
+}
+
+void KRB5_CALLCONV
+krb5int_free_plugin_dir_data (void **ptrs)
+{
+ /* Nothing special to be done per pointer. */
+ free(ptrs);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5int_get_plugin_dir_data (struct plugin_dir_handle *dirhandle,
+ const char *symname,
+ void ***ptrs)
+{
+ void **p, **newp, *sym;
+ int count, i, err;
+
+ if (dirhandle == NULL) {
+ *ptrs = 0;
+ return 0;
+ }
+
+ /* XXX Do we need to add a leading "_" to the symbol name on any
+ modern platforms? */
+
+ Tprintf("get_plugin_data_sym(%s)\n", symname);
+ p = 0;
+ count = 0;
+ for (i = 0; !NULL_HANDLE (&dirhandle->files[i]); i++) {
+ Tprintf(" -> dlsym(%p,%s)\n", dirhandle->files[i].dlhandle, symname);
+ sym = dlsym(dirhandle->files[i].dlhandle, symname);
+ if (sym == NULL) {
+ const char *e = dlerror();
+ Tprintf(" -> %s\n", e);
+ continue;
+ } else {
+ Tprintf(" -> %p\n", sym);
+ }
+ newp = realloc (p, (count+1) * sizeof(*p));
+ if (newp == NULL) {
+ realloc_failure:
+ err = errno;
+ free(p);
+ return err;
+ }
+ p = newp;
+ p[count] = sym;
+ count++;
+ }
+ newp = realloc(p, (count+1) * sizeof(*p));
+ if (newp == NULL)
+ goto realloc_failure;
+ p = newp;
+ p[count] = NULL;
+ *ptrs = p;
+ {
+ i = 0;
+ do {
+ Tprintf(" p[%d] = %p\n", i, p[i]);
+ } while (p[i++]);
+ }
+ return 0;
+}
+
+void KRB5_CALLCONV
+krb5int_free_plugin_dir_func (void (**ptrs)(void))
+{
+ /* Nothing special to be done per pointer. */
+ free(ptrs);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5int_get_plugin_dir_func (struct plugin_dir_handle *dirhandle,
+ const char *symname,
+ void (***ptrs)(void))
+{
+ void (**p)(void), (**newp)(void), (*sym)(void);
+ int count, i, err;
+
+ if (dirhandle == NULL) {
+ *ptrs = 0;
+ return 0;
+ }
+
+ /* XXX Do we need to add a leading "_" to the symbol name on any
+ modern platforms? */
+
+ p = 0;
+ count = 0;
+ for (i = 0; !NULL_HANDLE (&dirhandle->files[i]); i++) {
+ sym = (void(*)(void)) dlsym(dirhandle->files[i].dlhandle, symname);
+ if (sym == NULL)
+ continue;
+ newp = realloc (p, (count+1) * sizeof(*p));
+ if (newp == NULL) {
+ realloc_failure:
+ err = errno;
+ free(p);
+ return err;
+ }
+ p = newp;
+ p[count] = sym;
+ count++;
+ }
+ newp = realloc(p, (count+1) * sizeof(*p));
+ if (newp == NULL)
+ goto realloc_failure;
+ p[count] = NULL;
+ *ptrs = p;
+ return 0;
+}