summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config-files/krb5.conf.M8
-rw-r--r--src/include/Makefile.in5
-rw-r--r--src/include/k5-int.h11
-rw-r--r--src/include/osconf.hin3
-rw-r--r--src/lib/krb5/krb/Makefile.in2
-rw-r--r--src/lib/krb5/krb/init_ctx.c7
-rw-r--r--src/lib/krb5/krb/plugin.c86
7 files changed, 91 insertions, 31 deletions
diff --git a/src/config-files/krb5.conf.M b/src/config-files/krb5.conf.M
index b04d6efd69..33f3d920c1 100644
--- a/src/config-files/krb5.conf.M
+++ b/src/config-files/krb5.conf.M
@@ -284,6 +284,11 @@ true. Setting this flag to false is more secure, but may force
users to exclusively use fully qualified domain names when
authenticating to services.
+.IP plugin_base_dir
+If set, determines the base directory where krb5 plugins are located.
+The default value is the "krb5/plugins" subdirectory of the krb5
+library directory.
+
.SH APPDEFAULTS SECTION
Each tag in the [appdefaults] section names a Kerberos V5 application
@@ -732,8 +737,7 @@ This tag may have multiple values. Each value is a string of the form
"modulename:pathname", which causes the shared object located at
pathname to be registered as a dynamic module named modulename for the
pluggable interface. If pathname is not an absolute path, it will be
-treated as relative to the "krb5/plugins" subdirectory of the krb5
-library directory.
+treated as relative to the plugin base directory.
.IP enable_only
This tag may have multiple values. If there are values for this tag,
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index ed7d20fbb4..d6a9b3c389 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -65,8 +65,9 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(KRB5RCTMPDIR)+" \
-e "s+@SBINDIR+$(SBINDIR)+" \
-e "s+@MODULEDIR+$(MODULE_DIR)+" \
-e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \
- -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
- -e 's+@SYSCONFDIR+$(SYSCONFDIR)+'
+ -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
+ -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
+ -e 's+@DYNOBJEXT+$(DYNOBJEXT)+'
OSCONFSRC = $(srcdir)/osconf.hin
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 0a00f1d282..86ec114b0a 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -256,6 +256,7 @@ typedef INT64_TYPE krb5_int64;
#define KRB5_CONF_NO_HOST_REFERRAL "no_host_referral"
#define KRB5_CONF_PERMITTED_ENCTYPES "permitted_enctypes"
#define KRB5_CONF_PLUGINS "plugins"
+#define KRB5_CONF_PLUGIN_BASE_DIR "plugin_base_dir"
#define KRB5_CONF_PREAUTH_MODULE_DIR "preauth_module_dir"
#define KRB5_CONF_PREFERRED_PREAUTH_TYPES "preferred_preauth_types"
#define KRB5_CONF_PROXIABLE "proxiable"
@@ -1435,6 +1436,15 @@ krb5_error_code
k5_plugin_register(krb5_context context, int interface_id, const char *modname,
krb5_plugin_initvt_fn module);
+/*
+ * Register a plugin module which is part of the krb5 tree but is built as a
+ * dynamic plugin. Look for the module in modsubdir relative to the
+ * context->base_plugin_dir.
+ */
+krb5_error_code
+k5_plugin_register_dyn(krb5_context context, int interface_id,
+ const char *modname, const char *modsubdir);
+
/* Destroy the module state within context; used by krb5_free_context. */
void
k5_plugin_free_context(krb5_context context);
@@ -1496,6 +1506,7 @@ struct _krb5_context {
void *trace_callback_data;
struct plugin_interface plugins[PLUGIN_NUM_INTERFACES];
+ char *plugin_base_dir;
};
/* could be used in a table to find an etype and initialize a block */
diff --git a/src/include/osconf.hin b/src/include/osconf.hin
index 073ce1422f..04f10ce82e 100644
--- a/src/include/osconf.hin
+++ b/src/include/osconf.hin
@@ -59,6 +59,9 @@
#define DEFAULT_LNAME_FILENAME "@PREFIX/lib/krb5.aname"
#endif /* _WINDOWS */
+#define DEFAULT_PLUGIN_BASE_DIR "@LIBDIR/krb5/plugins"
+#define PLUGIN_EXT "@DYNOBJEXT"
+
#define DEFAULT_KDB_FILE "@LOCALSTATEDIR/krb5kdc/principal"
#define DEFAULT_KEYFILE_STUB "@LOCALSTATEDIR/krb5kdc/.k5."
#define KRB5_DEFAULT_ADMIN_ACL "@LOCALSTATEDIR/krb5kdc/krb5_adm.acl"
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 6a0faf29db..6a93718369 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -4,7 +4,7 @@ RUN_SETUP = @KRB5_RUN_ENV@
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
LOCALINCLUDES = -I$(srcdir)/../os -I$(top_srcdir)
-DEFS=-DLIBDIR=\"$(KRB5_LIBDIR)\"
+DEFS=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DDYNOBJEXT=\"$(DYNOBJEXT)\"
##DOS##BUILDTOP = ..\..\..
##DOS##PREFIXDIR=krb
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 99ff5fcdef..657b2dbb31 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -230,6 +230,13 @@ init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
&tmp);
ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
+ retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
+ KRB5_CONF_PLUGIN_BASE_DIR, 0,
+ DEFAULT_PLUGIN_BASE_DIR,
+ &ctx->plugin_base_dir);
+ if (retval)
+ goto cleanup;
+
/*
* We use a default file credentials cache of 3. See
* lib/krb5/krb/ccache/file/fcc.h for a description of the
diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c
index 446d4f22e6..a9d6b06a7b 100644
--- a/src/lib/krb5/krb/plugin.c
+++ b/src/lib/krb5/krb/plugin.c
@@ -136,25 +136,26 @@ parse_modstr(krb5_context context, const char *modstr,
* plugins directory.
*/
static krb5_error_code
-expand_relative_modpath(const char *modpath, char **full_modpath_out)
+expand_relative_modpath(krb5_context context, const char *modpath,
+ char **full_modpath_out)
{
- char *fullpath;
+ char *path;
*full_modpath_out = NULL;
/* XXX Unix-specific path handling for now. */
if (*modpath == '/') {
/* We already have an absolute path. */
- fullpath = strdup(modpath);
- if (fullpath == NULL)
+ path = strdup(modpath);
+ if (path == NULL)
return ENOMEM;
} else {
/* Append the relative path to the system plugins directory. */
- if (asprintf(&fullpath, "%s/%s", LIBDIR "/krb5/plugins", modpath) < 0)
+ if (asprintf(&path, "%s/%s", context->plugin_base_dir, modpath) < 0)
return ENOMEM;
}
- *full_modpath_out = fullpath;
+ *full_modpath_out = path;
return 0;
}
@@ -195,28 +196,15 @@ filter_builtins(krb5_context context, struct plugin_interface *interface,
}
}
-/* Register the plugin module given by the profile string mod. */
static krb5_error_code
register_dyn_module(krb5_context context, struct plugin_interface *interface,
- const char *iname, const char *modstr, char **enable,
- char **disable)
+ const char *iname, const char *modname, const char *path)
{
krb5_error_code ret;
- char *modname = NULL, *modpath = NULL, *full_modpath = NULL;
char *symname = NULL;
struct plugin_file_handle *handle = NULL;
void (*initvt_fn)();
- /* Parse out the module name and path, and make sure it is enabled. */
- ret = parse_modstr(context, modstr, &modname, &modpath);
- if (ret != 0)
- goto cleanup;
- ret = expand_relative_modpath(modpath, &full_modpath);
- if (ret != 0)
- goto cleanup;
- if (!module_enabled(modname, enable, disable))
- goto cleanup;
-
/* Construct the initvt symbol name for this interface and module. */
if (asprintf(&symname, "%s_%s_initvt", iname, modname) < 0) {
symname = NULL;
@@ -225,7 +213,7 @@ register_dyn_module(krb5_context context, struct plugin_interface *interface,
}
/* Open the plugin and resolve the initvt symbol. */
- ret = krb5int_open_plugin(full_modpath, &handle, &context->err);
+ ret = krb5int_open_plugin(path, &handle, &context->err);
if (ret != 0)
goto cleanup;
ret = krb5int_get_plugin_func(handle, symname, &initvt_fn, &context->err);
@@ -240,15 +228,40 @@ register_dyn_module(krb5_context context, struct plugin_interface *interface,
handle = NULL; /* Now owned by the module mapping. */
cleanup:
- free(modname);
- free(modpath);
- free(full_modpath);
free(symname);
if (handle != NULL)
krb5int_close_plugin(handle);
return ret;
}
+/* Register the plugin module given by the profile string mod, if enabled
+ * according to the values of enable and disable. */
+static krb5_error_code
+register_dyn_mapping(krb5_context context, struct plugin_interface *interface,
+ const char *iname, const char *modstr, char **enable,
+ char **disable)
+{
+ krb5_error_code ret;
+ char *modname = NULL, *modpath = NULL, *fullpath = NULL;
+
+ /* Parse out the module name and path, and make sure it is enabled. */
+ ret = parse_modstr(context, modstr, &modname, &modpath);
+ if (ret != 0)
+ goto cleanup;
+ ret = expand_relative_modpath(context, modpath, &fullpath);
+ if (ret != 0)
+ goto cleanup;
+ if (!module_enabled(modname, enable, disable))
+ goto cleanup;
+ ret = register_dyn_module(context, interface, iname, modname, fullpath);
+
+cleanup:
+ free(modname);
+ free(modpath);
+ free(fullpath);
+ return ret;
+}
+
/* Ensure that a plugin interface is configured. id is assumed to be valid. */
static krb5_error_code
configure_interface(krb5_context context, int id)
@@ -284,8 +297,8 @@ configure_interface(krb5_context context, int id)
/* Create mappings for dynamic modules which aren't filtered out. */
for (mod = modules; mod && *mod; mod++) {
- ret = register_dyn_module(context, interface, iname, *mod,
- enable, disable);
+ ret = register_dyn_mapping(context, interface, iname, *mod,
+ enable, disable);
if (ret != 0)
return ret;
}
@@ -380,6 +393,27 @@ k5_plugin_register(krb5_context context, int interface_id, const char *modname,
return register_module(context, interface, modname, module, NULL);
}
+krb5_error_code
+k5_plugin_register_dyn(krb5_context context, int interface_id,
+ const char *modname, const char *modsubdir)
+{
+ krb5_error_code ret;
+ struct plugin_interface *interface = get_interface(context, interface_id);
+ char *path;
+
+ /* Disallow registering plugins after load. */
+ if (interface == NULL || interface->configured)
+ return EINVAL;
+ if (asprintf(&path, "%s/%s/%s%s", context->plugin_base_dir, modsubdir,
+ modname, PLUGIN_EXT) < 0)
+ return ENOMEM;
+
+ ret = register_dyn_module(context, interface,
+ interface_names[interface_id], modname, path);
+ free(path);
+ return ret;
+}
+
void
k5_plugin_free_context(krb5_context context)
{