summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common/ldb_modules.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb/common/ldb_modules.c')
-rw-r--r--source4/lib/ldb/common/ldb_modules.c153
1 files changed, 107 insertions, 46 deletions
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index 922506ea4d..f1b4783fca 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -67,7 +67,7 @@ static char *talloc_strdup_no_spaces(struct ldb_context *ldb, const char *string
/* modules are called in inverse order on the stack.
Lets place them as an admin would think the right order is.
- Modules order is imprtant */
+ Modules order is important */
static char **ldb_modules_list_from_string(struct ldb_context *ldb, const char *string)
{
char **modules = NULL;
@@ -109,35 +109,79 @@ static char **ldb_modules_list_from_string(struct ldb_context *ldb, const char *
return modules;
}
+static struct ops_list_entry {
+ const struct ldb_module_ops *ops;
+ struct ops_list_entry *next;
+} *registered_modules = NULL;
+
+static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
+{
+ struct ops_list_entry *e;
+
+ for (e = registered_modules; e; e = e->next) {
+ if (strcmp(e->ops->name, name) == 0)
+ return e->ops;
+ }
+
+ return NULL;
+}
+
+
+#ifndef STATIC_LIBLDB_MODULES
+#define STATIC_LIBLDB_MODULES \
+ { \
+ ldb_schema_init, \
+ ldb_operational_init, \
+ ldb_rdn_name_init, \
+ ldb_objectclass_init, \
+ ldb_paged_results_init, \
+ ldb_sort_init, \
+ NULL \
+ }
+#endif
+
+int ldb_global_init(void)
+{
+ static int (*static_init_fns[])(void) = STATIC_LIBLDB_MODULES;
+
+ static int initialized = 0;
+ int ret = 0, i;
+
+ if (initialized)
+ return 0;
+
+ initialized = 1;
+
+ for (i = 0; static_init_fns[i]; i++) {
+ if (static_init_fns[i]() == -1)
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int ldb_register_module(const struct ldb_module_ops *ops)
+{
+ struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
+
+ if (ldb_find_module_ops(ops->name) != NULL)
+ return -1;
+
+ if (entry == NULL)
+ return -1;
+
+ entry->ops = ops;
+ entry->next = registered_modules;
+ registered_modules = entry;
+
+ return 0;
+}
+
int ldb_load_modules(struct ldb_context *ldb, const char *options[])
{
char **modules = NULL;
+ struct ldb_module *module;
int i;
- const struct {
- const char *name;
- ldb_module_init_t init;
- } well_known_modules[] = {
- { "schema", schema_module_init },
- { "operational", operational_module_init },
- { "rdn_name", rdn_name_module_init },
- { "objectclass", objectclass_module_init },
- { "paged_results", paged_results_module_init },
- { "server_sort", server_sort_module_init },
- { "asq", asq_module_init },
-#ifdef _SAMBA_BUILD_
- { "objectguid", objectguid_module_init },
- { "samldb", samldb_module_init },
- { "samba3sam", ldb_samba3sam_module_init },
- { "proxy", proxy_module_init },
- { "rootdse", rootdse_module_init },
- { "extended_dn", extended_dn_module_init },
- { "password_hash", password_hash_module_init },
- { "kludge_acl", kludge_acl_module_init },
- { "wins_ldb", wins_ldb_module_init },
-#endif
- { NULL, NULL }
- };
-
/* find out which modules we are requested to activate */
/* check if we have a custom module list passd as ldb option */
@@ -149,7 +193,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
}
}
- /* if not overloaded by options and the backend is not ldap try to load the modules list form ldb */
+ /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) {
int ret;
const char * const attrs[] = { "@LIST" , NULL};
@@ -191,27 +235,34 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
for (i = 0; modules[i] != NULL; i++) {
struct ldb_module *current;
- int m;
- for (m=0;well_known_modules[m].name;m++) {
- if (strcmp(modules[i], well_known_modules[m].name) == 0) {
- current = well_known_modules[m].init(ldb, options);
- if (current == NULL) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "function 'init_module' in %s fails\n", modules[i]);
- return -1;
- }
- DLIST_ADD(ldb->modules, current);
- break;
- }
- }
- if (well_known_modules[m].name == NULL) {
+ const struct ldb_module_ops *ops;
+
+ ops = ldb_find_module_ops(modules[i]);
+ if (ops == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n",
modules[i]);
+ continue;
}
+
+ current = talloc_zero(ldb, struct ldb_module);
+ if (current == NULL) {
+ return -1;
+ }
+
+ current->ldb = ldb;
+ current->ops = ops;
+
+ DLIST_ADD(ldb->modules, current);
}
- /* second stage init */
- if (ldb_second_stage_init(ldb) != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: Second stage init failed!\n");
+ module = ldb->modules;
+
+ while (module && module->ops->init_context == NULL)
+ module = module->next;
+
+ if (module && module->ops->init_context &&
+ module->ops->init_context(module) != LDB_SUCCESS) {
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n");
return -1;
}
@@ -240,10 +291,20 @@ int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
return module->ops->request(module, request);
}
-int ldb_next_second_stage_init(struct ldb_module *module)
+int ldb_next_init(struct ldb_module *module)
{
- FIND_OP(module, second_stage_init);
- return module->ops->second_stage_init(module);
+ /* init is different in that it is not an error if modules
+ * do not require initialization */
+
+ module = module->next;
+
+ while (module && module->ops->init_context == NULL)
+ module = module->next;
+
+ if (module == NULL)
+ return LDB_SUCCESS;
+
+ return module->ops->init_context(module);
}
int ldb_next_start_trans(struct ldb_module *module)