From bb1909e15e7a9f3cd79da2ce8b8ef90f1a557376 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 20 Mar 2006 21:44:59 +0000 Subject: r14592: Add support for loading shared modules to LDB. (This used to be commit f10fae23f0685b2d9c6174596e1c66d799f02c52) --- source4/build/smb_build/TODO | 1 - source4/build/smb_build/makefile.pm | 2 +- source4/dsdb/samdb/ldb_modules/config.mk | 48 ++++++++++++++++---------------- source4/lib/ldb/common/ldb.c | 15 ++++++++-- source4/lib/ldb/common/ldb_modules.c | 39 ++++++++++++++++++++++++++ source4/lib/ldb/config.mk | 1 + source4/lib/ldb/configure.in | 10 ++++++- source4/lib/ldb/include/includes.h | 3 ++ source4/lib/ldb/include/ldb_private.h | 1 + source4/lib/ldb/ldb.pc.in | 2 ++ source4/lib/ldb/ldb_ildap/ldb_ildap.c | 4 ++- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 4 ++- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- source4/nbt_server/config.mk | 6 ++-- 14 files changed, 103 insertions(+), 35 deletions(-) diff --git a/source4/build/smb_build/TODO b/source4/build/smb_build/TODO index 73e296c578..de6a1a101d 100644 --- a/source4/build/smb_build/TODO +++ b/source4/build/smb_build/TODO @@ -3,7 +3,6 @@ libcli_cldap.so.0.0.1 (rename to libcldap?) libcli_nbt.so.0.0.1 (rename to libnbt?) libcli_wrepl.so.0.0.1 (rename to libwrepl?) -- plugin loading support in ldb - generate headermap.txt set of test scripts that check the code: diff --git a/source4/build/smb_build/makefile.pm b/source4/build/smb_build/makefile.pm index a6d6d2b741..3d7412f5f3 100644 --- a/source4/build/smb_build/makefile.pm +++ b/source4/build/smb_build/makefile.pm @@ -441,7 +441,7 @@ sub PkgConfig($$) "", "$ctx->{VERSION}", $ctx->{DESCRIPTION}, - 1 + defined($ctx->{INIT_FUNCTIONS}) ); } diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 1afdb2d35b..c7ac5816e1 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -1,65 +1,65 @@ ################################################ -# Start MODULE libldb_objectguid -[MODULE::libldb_objectguid] +# Start MODULE ldb_objectguid +[MODULE::ldb_objectguid] SUBSYSTEM = ldb INIT_FUNCTION = objectguid_module_init OBJ_FILES = \ objectguid.o REQUIRED_SUBSYSTEMS = \ LIBNDR NDR_MISC -# End MODULE libldb_objectguid +# End MODULE ldb_objectguid ################################################ ################################################ -# Start MODULE libldb_samldb -[MODULE::libldb_samldb] +# Start MODULE ldb_samldb +[MODULE::ldb_samldb] SUBSYSTEM = ldb INIT_FUNCTION = samldb_module_init OBJ_FILES = \ samldb.o REQUIRED_SUBSYSTEMS = SAMDB # -# End MODULE libldb_samldb +# End MODULE ldb_samldb ################################################ ################################################ -# Start MODULE libldb_samba3sam -[MODULE::libldb_samba3sam] +# Start MODULE ldb_samba3sam +[MODULE::ldb_samba3sam] SUBSYSTEM = ldb INIT_FUNCTION = ldb_samba3sam_module_init ENABLE = NO OBJ_FILES = \ samba3sam.o # -# End MODULE libldb_samldb +# End MODULE ldb_samldb ################################################ ################################################ -# Start MODULE libldb_proxy -[MODULE::libldb_proxy] +# Start MODULE ldb_proxy +[MODULE::ldb_proxy] SUBSYSTEM = ldb INIT_FUNCTION = proxy_module_init OBJ_FILES = \ proxy.o # -# End MODULE libldb_proxy +# End MODULE ldb_proxy ################################################ ################################################ -# Start MODULE libldb_rootdse -[MODULE::libldb_rootdse] +# Start MODULE ldb_rootdse +[MODULE::ldb_rootdse] SUBSYSTEM = ldb INIT_FUNCTION = rootdse_module_init OBJ_FILES = \ rootdse.o # -# End MODULE libldb_rootdse +# End MODULE ldb_rootdse ################################################ ################################################ -# Start MODULE libldb_password_hash -[MODULE::libldb_password_hash] +# Start MODULE ldb_password_hash +[MODULE::ldb_password_hash] SUBSYSTEM = ldb INIT_FUNCTION = password_hash_module_init OBJ_FILES = \ @@ -67,12 +67,12 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = \ HEIMDAL_HDB HEIMDAL_KRB5 # -# End MODULE libldb_rootdse +# End MODULE ldb_rootdse ################################################ ################################################ -# Start MODULE libldb_cludge_acl -[MODULE::libldb_kludge_acl] +# Start MODULE ldb_cludge_acl +[MODULE::ldb_kludge_acl] SUBSYSTEM = ldb INIT_FUNCTION = ldb_kludge_acl_init OBJ_FILES = \ @@ -80,17 +80,17 @@ OBJ_FILES = \ REQUIRED_SUBSYSTEMS = \ LIB_SECURITY # -# End MODULE libldb_rootdse +# End MODULE ldb_rootdse ################################################ ################################################ -# Start MODULE libldb_extended_dn -[MODULE::libldb_extended_dn] +# Start MODULE ldb_extended_dn +[MODULE::ldb_extended_dn] SUBSYSTEM = ldb INIT_FUNCTION = ldb_extended_dn_init OBJ_FILES = \ extended_dn.o # -# End MODULE libldb_extended_dn +# End MODULE ldb_extended_dn ################################################ diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 9acf74535b..0d424ad601 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -102,15 +102,26 @@ static ldb_connect_fn ldb_find_backend(const char *url) int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]) { int ret; + char *backend; ldb_connect_fn fn; if (strchr(url, ':') != NULL) { - fn = ldb_find_backend(url); + backend = talloc_strndup(ldb, url, strchr(url, ':')-url); } else { /* Default to tdb */ - fn = ldb_find_backend("tdb:"); + backend = talloc_strdup(ldb, "tdb"); } + fn = ldb_find_backend(backend); + + if (fn == NULL) { + if (ldb_try_load_dso(ldb, backend) == 0) { + fn = ldb_find_backend(backend); + } + } + + talloc_free(backend); + if (fn == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url); return LDB_ERR_OTHER; diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 0cb0041d84..6ba5fbbc20 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -195,6 +195,39 @@ int ldb_register_module(const struct ldb_module_ops *ops) return 0; } +int ldb_try_load_dso(struct ldb_context *ldb, const char *name) +{ + char *path; + void *handle; + int (*init_fn) (void); + +#ifdef HAVE_DLOPEN + path = talloc_asprintf(ldb, "%s/%s.%s", MODULESDIR, name, SHLIBEXT); + + ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path); + + handle = dlopen(path, 0); + if (handle == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror()); + return -1; + } + + init_fn = dlsym(handle, "init_module"); + + if (init_fn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `init_module' found in %s: %s\n", path, dlerror()); + return -1; + } + + talloc_free(path); + + return init_fn(); +#else + ldb_debug(ldb, LDB_DEBUG_TRACE, "no dlopen() - not trying to load %s module\n", name); + return -1; +#endif +} + int ldb_load_modules(struct ldb_context *ldb, const char *options[]) { char **modules = NULL; @@ -252,6 +285,12 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) const struct ldb_module_ops *ops; ops = ldb_find_module_ops(modules[i]); + if (ops == NULL) { + if (ldb_try_load_dso(ldb, modules[i]) == 0) { + ops = ldb_find_module_ops(modules[i]); + } + } + if (ops == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", modules[i]); diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk index 661c31d027..20d1437288 100644 --- a/source4/lib/ldb/config.mk +++ b/source4/lib/ldb/config.mk @@ -132,6 +132,7 @@ REQUIRED_SUBSYSTEMS = \ VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = LDAP-like embedded database library +EXTRA_CFLAGS = -DMODULESDIR="$(MODULESDIR)/ldb" -DSHLIBEXT="$(SHLIBEXT)" INIT_FUNCTION_TYPE = int (*) (void) OBJ_FILES = \ common/ldb.o \ diff --git a/source4/lib/ldb/configure.in b/source4/lib/ldb/configure.in index 385c0caef0..54ec24df4d 100644 --- a/source4/lib/ldb/configure.in +++ b/source4/lib/ldb/configure.in @@ -23,8 +23,16 @@ AC_FUNC_MMAP AC_PATH_PROG(XSLTPROC,xsltproc) AC_PATH_PROG(DOXYGEN,doxygen) AC_PATH_PROG(GCOV,gcov) -AC_CHECK_HEADERS(stdint.h) +AC_CHECK_HEADERS(stdint.h dlfcn.h) AC_CONFIG_HEADER(include/config.h) +AC_CHECK_FUNCS(dlopen dlsym dlclose) + +SHLIBEXT="so" # Should be set based on OS later on +AC_SUBST(SHLIBEXT) + +MODULESDIR="$libdir/ldb" +AC_DEFINE(MODULESDIR,$MODULESDIR,[Modules directory]) +AC_SUBST(MODULESDIR) AC_CHECK_LIB(popt, poptGetContext) diff --git a/source4/lib/ldb/include/includes.h b/source4/lib/ldb/include/includes.h index c85ffadb6d..26309df381 100644 --- a/source4/lib/ldb/include/includes.h +++ b/source4/lib/ldb/include/includes.h @@ -34,6 +34,9 @@ #ifdef HAVE_STDINT_H #include #endif +#ifdef HAVE_DLFCN_H +#include +#endif #define discard_const(ptr) ((void *)((intptr_t)(ptr))) #define discard_const_p(type, ptr) ((type *)discard_const(ptr)) diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 27b6883c3d..0ea6c4e9de 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -135,6 +135,7 @@ void ldb_reset_err_string(struct ldb_context *ldb); int ldb_register_module(const struct ldb_module_ops *); int ldb_register_backend(const char *url_prefix, ldb_connect_fn); +int ldb_try_load_dso(struct ldb_context *ldb, const char *name); /* The following definitions come from lib/ldb/common/ldb_debug.c */ void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in index e524fbed36..8b0536e21e 100644 --- a/source4/lib/ldb/ldb.pc.in +++ b/source4/lib/ldb/ldb.pc.in @@ -2,9 +2,11 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +modulesdir=@modulesdir@ Name: ldb Description: An LDAP-like embedded database Version: 4.0 Libs: @LIBS@ -L${libdir} -lldb Cflags: -I${includedir} @CFLAGS@ +Modulesdir: ${modulesdir} diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 2b43193864..3c6101bb1a 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -1069,5 +1069,7 @@ failed: int ldb_ildap_init(void) { - return ldb_register_backend("ldap", ildb_connect); + return ldb_register_backend("ldap", ildb_connect) + + ldb_register_backend("ldapi", ildb_connect) + + ldb_register_backend("ldaps", ildb_connect); } diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 49de229a1e..8bfff117da 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -1105,5 +1105,7 @@ failed: int ldb_ldap_init(void) { - return ldb_register_backend("ldap", lldb_connect); + return ldb_register_backend("ldap", lldb_connect) + + ldb_register_backend("ldapi", lldb_connect) + + ldb_register_backend("ldaps", lldb_connect); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index bc936eb71e..3a1a08aafd 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1102,5 +1102,5 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, int ldb_tdb_init(void) { - return ldb_register_backend("tdb:", ltdb_connect); + return ldb_register_backend("tdb", ltdb_connect); } diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk index 000ddce18c..6af0f32e63 100644 --- a/source4/nbt_server/config.mk +++ b/source4/nbt_server/config.mk @@ -13,15 +13,15 @@ REQUIRED_SUBSYSTEMS = \ ####################### ####################### -# Start MODULE libldb_wins_ldb -[MODULE::libldb_wins_ldb] +# Start MODULE ldb_wins_ldb +[MODULE::ldb_wins_ldb] SUBSYSTEM = ldb INIT_FUNCTION = wins_ldb_module_init OBJ_FILES = \ wins/wins_ldb.o REQUIRED_SUBSYSTEMS = \ LIBNETIF -# End MODULE libldb_wins_ldb +# End MODULE ldb_wins_ldb ####################### ####################### -- cgit