dovecot-2.0: module_dir_load(): Added support for checking binar...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 7 17:20:20 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/10ff5c7e7f40
changeset: 11748:10ff5c7e7f40
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jul 07 15:18:46 2010 +0100
description:
module_dir_load(): Added support for checking binary name dependency.

diffstat:

 src/lib/module-dir.c |  45 ++++++++++++++++++++++++++++++++++++++-------
 src/lib/module-dir.h |   3 +++
 2 files changed, 41 insertions(+), 7 deletions(-)

diffs (91 lines):

diff -r 4db258f7ce91 -r 10ff5c7e7f40 src/lib/module-dir.c
--- a/src/lib/module-dir.c	Wed Jul 07 14:58:05 2010 +0100
+++ b/src/lib/module-dir.c	Wed Jul 07 15:18:46 2010 +0100
@@ -67,8 +67,29 @@
 }
 
 static bool
-module_check_missing_dependencies(struct module *module,
-				  struct module *all_modules)
+module_check_wrong_binary_dependency(const struct module_dir_load_settings *set,
+				     struct module *module)
+{
+	const char *symbol_name, *binary_dep;
+
+	symbol_name = t_strconcat(module->name, "_binary_dependency", NULL);
+	binary_dep = dlsym(module->handle, symbol_name);
+	if (binary_dep == NULL)
+		return TRUE;
+
+	if (set->binary_name == NULL ||
+	    strcmp(binary_dep, set->binary_name) == 0)
+		return TRUE;
+
+	i_error("Can't load plugin %s: "
+		"Plugin is intended to be used only by %s binary (we're %s)",
+		module->name, binary_dep, set->binary_name);
+	return FALSE;
+}
+
+static bool
+module_check_missing_plugin_dependencies(struct module *module,
+					 struct module *all_modules)
 {
 	const char **deps;
 	struct module *m;
@@ -134,6 +155,7 @@
 	void *handle;
 	struct module *module;
 	const char *const *module_version;
+	bool failed = FALSE;
 
 	if (set->ignore_dlopen_errors) {
 		handle = quiet_dlopen(path, RTLD_GLOBAL | RTLD_NOW);
@@ -143,7 +165,16 @@
 		handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW);
 		if (handle == NULL) {
 			i_error("dlopen(%s) failed: %s", path, dlerror());
+#ifdef RTLD_LAZY
+			failed = TRUE;
+			/* try to give a better error message by lazily loading
+			   the plugin and checking its dependencies */
+			handle = dlopen(path, RTLD_LAZY);
+			if (handle == NULL)
+				return NULL;
+#else
 			return NULL;
+#endif
 		}
 	}
 
@@ -174,12 +205,12 @@
 	    set->require_init_funcs) {
 		i_error("Module doesn't have %s function: %s",
 			module->init == NULL ? "init" : "deinit", path);
-		module->deinit = NULL;
-		module_free(module);
-		return NULL;
-	}
+		failed = TRUE;
+	} else if (!module_check_wrong_binary_dependency(set, module) ||
+		   !module_check_missing_plugin_dependencies(module, all_modules))
+		failed = TRUE;
 
-	if (!module_check_missing_dependencies(module, all_modules)) {
+	if (failed) {
 		module->deinit = NULL;
 		module_free(module);
 		return NULL;
diff -r 4db258f7ce91 -r 10ff5c7e7f40 src/lib/module-dir.h
--- a/src/lib/module-dir.h	Wed Jul 07 14:58:05 2010 +0100
+++ b/src/lib/module-dir.h	Wed Jul 07 15:18:46 2010 +0100
@@ -5,6 +5,9 @@
 	/* If version is non-NULL and the module contains a version symbol,
 	   fail the load if they're different. */
 	const char *version;
+	/* Binary name used for checking if plugin is tried to be loaded for
+	   wrong binary. */
+	const char *binary_name;
 
 	/* Require all plugins to have <plugin_name>_init() function */
 	unsigned int require_init_funcs:1;


More information about the dovecot-cvs mailing list