summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-06-28 10:49:49 +0200
committerStefan Metzmacher <metze@samba.org>2008-06-30 09:14:07 +0200
commit5ccfd6a90ed81209d055524be51f54cc2f5d8de6 (patch)
tree10013c8cbb5cef32e3285ee0fa6ed92779aafcb2 /source4/lib
parentd7ac45f8b851352867fa0f039d3a99bbc7016a68 (diff)
downloadsamba-5ccfd6a90ed81209d055524be51f54cc2f5d8de6.tar.gz
samba-5ccfd6a90ed81209d055524be51f54cc2f5d8de6.tar.bz2
samba-5ccfd6a90ed81209d055524be51f54cc2f5d8de6.zip
ldb: allow ldb modules to specify LDB_MODULE(name) or LDB_BACKEND(name)
metze (This used to be commit 1d5b714438a955d76f92f4ccd8aa2f7f89ffa5fd)
Diffstat (limited to 'source4/lib')
-rw-r--r--source4/lib/ldb/common/ldb.c147
-rw-r--r--source4/lib/ldb/common/ldb_modules.c214
-rw-r--r--source4/lib/ldb/config.mk3
-rw-r--r--source4/lib/ldb/ldb_ildap/config.mk1
4 files changed, 201 insertions, 164 deletions
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index cac0a383d8..ce4796dee2 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -68,153 +68,6 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct event_context *ev_ctx)
return ldb;
}
-static struct backends_list_entry {
- struct ldb_backend_ops *ops;
- struct backends_list_entry *prev, *next;
-} *ldb_backends = NULL;
-
-#ifndef STATIC_LIBLDB_BACKENDS
-
-#ifdef HAVE_LDB_LDAP
-#define LDAP_INIT &ldb_ldap_backend_ops, \
- &ldb_ldapi_backend_ops, \
- &ldb_ldaps_backend_ops,
-#else
-#define LDAP_INIT
-#endif
-
-#ifdef HAVE_LDB_SQLITE3
-#define SQLITE3_INIT &ldb_sqlite3_backend_ops,
-#else
-#define SQLITE3_INIT
-#endif
-
-#define STATIC_LIBLDB_BACKENDS \
- LDAP_INIT \
- SQLITE3_INIT \
- &ldb_tdb_backend_ops, \
- NULL
-#endif
-
-const static struct ldb_backend_ops *builtin_backends[] = {
- STATIC_LIBLDB_BACKENDS
-};
-
-static ldb_connect_fn ldb_find_backend(const char *url)
-{
- struct backends_list_entry *backend;
- int i;
-
- for (i = 0; builtin_backends[i]; i++) {
- if (strncmp(builtin_backends[i]->name, url,
- strlen(builtin_backends[i]->name)) == 0)
- return builtin_backends[i]->connect_fn;
- }
-
- for (backend = ldb_backends; backend; backend = backend->next) {
- if (strncmp(backend->ops->name, url,
- strlen(backend->ops->name)) == 0) {
- return backend->ops->connect_fn;
- }
- }
-
- return NULL;
-}
-
-/*
- register a new ldb backend
-*/
-int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
-{
- struct ldb_backend_ops *backend;
- struct backends_list_entry *entry;
-
- backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);
- if (!backend) return LDB_ERR_OPERATIONS_ERROR;
-
- entry = talloc(talloc_autofree_context(), struct backends_list_entry);
- if (!entry) {
- talloc_free(backend);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ldb_find_backend(url_prefix)) {
- return LDB_SUCCESS;
- }
-
- /* Maybe check for duplicity here later on? */
-
- backend->name = talloc_strdup(backend, url_prefix);
- backend->connect_fn = connectfn;
- entry->ops = backend;
- DLIST_ADD(ldb_backends, entry);
-
- return LDB_SUCCESS;
-}
-
-/*
- Return the ldb module form of a database.
- The URL can either be one of the following forms
- ldb://path
- ldapi://path
-
- flags is made up of LDB_FLG_*
-
- the options are passed uninterpreted to the backend, and are
- backend specific.
-
- This allows modules to get at only the backend module, for example where a
- module may wish to direct certain requests at a particular backend.
-*/
-int ldb_connect_backend(struct ldb_context *ldb,
- const char *url,
- const char *options[],
- struct ldb_module **backend_module)
-{
- int ret;
- char *backend;
- ldb_connect_fn fn;
-
- if (strchr(url, ':') != NULL) {
- backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
- } else {
- /* Default to tdb */
- backend = talloc_strdup(ldb, "tdb");
- }
-
- fn = ldb_find_backend(backend);
-
- if (fn == NULL) {
- struct ldb_backend_ops *ops;
- char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend);
- if (symbol_name == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ops = ldb_dso_load_symbol(ldb, backend, symbol_name);
- if (ops != NULL) {
- fn = ops->connect_fn;
- }
- talloc_free(symbol_name);
- }
-
- talloc_free(backend);
-
- if (fn == NULL) {
- ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to find backend for '%s'\n", url);
- return LDB_ERR_OTHER;
- }
-
- ret = fn(ldb, url, ldb->flags, options, backend_module);
-
- if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Failed to connect to '%s'\n", url);
- return ret;
- }
- return ret;
-}
-
/*
try to autodetect a basedn if none specified. This fixes one of my
pet hates about ldapsearch, which is that you have to get a long,
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index fbfb5e5322..4d69dc662e 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -120,36 +120,149 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
return m;
}
+static struct backends_list_entry {
+ struct ldb_backend_ops *ops;
+ struct backends_list_entry *prev, *next;
+} *ldb_backends = NULL;
+
static struct ops_list_entry {
const struct ldb_module_ops *ops;
struct ops_list_entry *next;
} *registered_modules = NULL;
-#define LDB_MODULE(name) (&ldb_ ## name ## _module_ops)
+static const struct ldb_builtins {
+ const struct ldb_backend_ops *backend_ops;
+ const struct ldb_module_ops *module_ops;
+} builtins[];
-#ifndef STATIC_LIBLDB_MODULES
+static ldb_connect_fn ldb_find_backend(const char *url)
+{
+ struct backends_list_entry *backend;
+ int i;
-#define STATIC_LIBLDB_MODULES \
- LDB_MODULE(operational), \
- LDB_MODULE(rdn_name), \
- LDB_MODULE(paged_results), \
- LDB_MODULE(server_sort), \
- LDB_MODULE(asq), \
- NULL
-#endif
+ for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
+ if (builtins[i].backend_ops == NULL) continue;
-const static struct ldb_module_ops *builtin_modules[] = {
- STATIC_LIBLDB_MODULES
-};
+ if (strncmp(builtins[i].backend_ops->name, url,
+ strlen(builtins[i].backend_ops->name)) == 0) {
+ return builtins[i].backend_ops->connect_fn;
+ }
+ }
+
+ for (backend = ldb_backends; backend; backend = backend->next) {
+ if (strncmp(backend->ops->name, url,
+ strlen(backend->ops->name)) == 0) {
+ return backend->ops->connect_fn;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ register a new ldb backend
+*/
+int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
+{
+ struct ldb_backend_ops *backend;
+ struct backends_list_entry *entry;
+
+ backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);
+ if (!backend) return LDB_ERR_OPERATIONS_ERROR;
+
+ entry = talloc(talloc_autofree_context(), struct backends_list_entry);
+ if (!entry) {
+ talloc_free(backend);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (ldb_find_backend(url_prefix)) {
+ return LDB_SUCCESS;
+ }
+
+ /* Maybe check for duplicity here later on? */
+
+ backend->name = talloc_strdup(backend, url_prefix);
+ backend->connect_fn = connectfn;
+ entry->ops = backend;
+ DLIST_ADD(ldb_backends, entry);
+
+ return LDB_SUCCESS;
+}
+
+/*
+ Return the ldb module form of a database.
+ The URL can either be one of the following forms
+ ldb://path
+ ldapi://path
+
+ flags is made up of LDB_FLG_*
+
+ the options are passed uninterpreted to the backend, and are
+ backend specific.
+
+ This allows modules to get at only the backend module, for example where a
+ module may wish to direct certain requests at a particular backend.
+*/
+int ldb_connect_backend(struct ldb_context *ldb,
+ const char *url,
+ const char *options[],
+ struct ldb_module **backend_module)
+{
+ int ret;
+ char *backend;
+ ldb_connect_fn fn;
+
+ if (strchr(url, ':') != NULL) {
+ backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
+ } else {
+ /* Default to tdb */
+ backend = talloc_strdup(ldb, "tdb");
+ }
+
+ fn = ldb_find_backend(backend);
+
+ if (fn == NULL) {
+ struct ldb_backend_ops *ops;
+ char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend);
+ if (symbol_name == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ops = ldb_dso_load_symbol(ldb, backend, symbol_name);
+ if (ops != NULL) {
+ fn = ops->connect_fn;
+ }
+ talloc_free(symbol_name);
+ }
+
+ talloc_free(backend);
+
+ if (fn == NULL) {
+ ldb_debug(ldb, LDB_DEBUG_FATAL,
+ "Unable to find backend for '%s'\n", url);
+ return LDB_ERR_OTHER;
+ }
+
+ ret = fn(ldb, url, ldb->flags, options, backend_module);
+
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(ldb, LDB_DEBUG_ERROR,
+ "Failed to connect to '%s'\n", url);
+ return ret;
+ }
+ return ret;
+}
static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
{
struct ops_list_entry *e;
int i;
- for (i = 0; builtin_modules[i]; i++) {
- if (strcmp(builtin_modules[i]->name, name) == 0)
- return builtin_modules[i];
+ for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {
+ if (builtins[i].module_ops == NULL) continue;
+
+ if (strcmp(builtins[i].module_ops->name, name) == 0)
+ return builtins[i].module_ops;
}
for (e = registered_modules; e; e = e->next) {
@@ -441,3 +554,72 @@ int ldb_next_del_trans(struct ldb_module *module)
FIND_OP(module, del_transaction);
return module->ops->del_transaction(module);
}
+
+#ifndef STATIC_LIBLDB_MODULES
+
+#ifdef HAVE_LDB_LDAP
+#define LDAP_BACKEND LDB_BACKEND(ldap), LDB_BACKEND(ldapi), LDB_BACKEND(ldaps),
+#else
+#define LDAP_BACKEND
+#endif
+
+#ifdef HAVE_LDB_SQLITE3
+#define SQLITE3_BACKEND LDB_BACKEND(sqlite3),
+#else
+#define SQLITE3_BACKEND
+#endif
+
+#define STATIC_LIBLDB_MODULES \
+ LDB_BACKEND(tdb), \
+ LDAP_BACKEND \
+ SQLITE3_BACKEND \
+ LDB_MODULE(operational), \
+ LDB_MODULE(rdn_name), \
+ LDB_MODULE(paged_results), \
+ LDB_MODULE(server_sort), \
+ LDB_MODULE(asq), \
+ NULL
+#endif
+
+/*
+ * this is a bit hacked, as STATIC_LIBLDB_MODULES contains ','
+ * between the elements and we want to autogenerate the
+ * extern struct declarations, so we do some hacks and let the
+ * ',' appear in an unused function prototype.
+ */
+#undef NULL
+#define NULL LDB_MODULE(NULL),
+
+#define LDB_BACKEND(name) \
+ int); \
+ extern const struct ldb_backend_ops ldb_ ## name ## _backend_ops;\
+ extern void ldb_noop ## name (int
+#define LDB_MODULE(name) \
+ int); \
+ extern const struct ldb_module_ops ldb_ ## name ## _module_ops;\
+ extern void ldb_noop ## name (int
+
+extern void ldb_start_noop(int,
+STATIC_LIBLDB_MODULES
+int);
+
+#undef NULL
+#define NULL { \
+ .backend_ops = (void *)0, \
+ .module_ops = (void *)0 \
+}
+
+#undef LDB_BACKEND
+#define LDB_BACKEND(name) { \
+ .backend_ops = &ldb_ ## name ## _backend_ops, \
+ .module_ops = (void *)0 \
+}
+#undef LDB_MODULE
+#define LDB_MODULE(name) { \
+ .backend_ops = (void *)0, \
+ .module_ops = &ldb_ ## name ## _module_ops \
+}
+
+static const struct ldb_builtins builtins[] = {
+ STATIC_LIBLDB_MODULES
+};
diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk
index 36a5870a3e..6821c058f2 100644
--- a/source4/lib/ldb/config.mk
+++ b/source4/lib/ldb/config.mk
@@ -92,6 +92,7 @@ ldb_skel_OBJ_FILES = $(ldbsrcdir)/modules/skel.o
SUBSYSTEM = LIBLDB
CFLAGS = -I$(ldbsrcdir)/include
PRIVATE_DEPENDENCIES = LIBTALLOC SQLITE3 LIBEVENTS
+INIT_FUNCTION = LDB_BACKEND(sqlite3)
# End MODULE ldb_sqlite3
################################################
@@ -104,6 +105,7 @@ SUBSYSTEM = LIBLDB
CFLAGS = -I$(ldbsrcdir)/include -I$(ldbsrcdir)/ldb_tdb
PRIVATE_DEPENDENCIES = \
LIBTDB LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_BACKEND(tdb)
# End MODULE ldb_tdb
################################################
@@ -114,7 +116,6 @@ ldb_tdb_OBJ_FILES = $(addprefix $(ldbsrcdir)/ldb_tdb/, ldb_tdb.o ldb_search.o ld
# Start SUBSYSTEM ldb
[LIBRARY::LIBLDB]
CFLAGS = -I$(ldbsrcdir)/include
-INIT_FUNCTION_TYPE = extern const struct ldb_module_ops
PUBLIC_DEPENDENCIES = \
LIBTALLOC LIBEVENTS
PRIVATE_DEPENDENCIES = \
diff --git a/source4/lib/ldb/ldb_ildap/config.mk b/source4/lib/ldb/ldb_ildap/config.mk
index 4247bd96b7..82d8267cfa 100644
--- a/source4/lib/ldb/ldb_ildap/config.mk
+++ b/source4/lib/ldb/ldb_ildap/config.mk
@@ -5,6 +5,7 @@ SUBSYSTEM = LIBLDB
CFLAGS = -I$(ldbsrcdir)/include
OUTPUT_TYPE = SHARED_LIBRARY
PRIVATE_DEPENDENCIES = LIBTALLOC LIBCLI_LDAP CREDENTIALS
+INIT_FUNCTION = LDB_BACKEND(ldapi),LDB_BACKEND(ldaps),LDB_BACKEND(ldap)
ALIASES = ldapi ldaps ldap
# End MODULE ldb_ildap
################################################