2009-09-22 04:52:21 +04:00
/*
2004-11-15 14:42:17 +03:00
ldb database library
2008-09-12 02:33:16 +04:00
Copyright ( C ) Simo Sorce 2004 - 2008
2004-11-15 14:42:17 +03:00
* * NOTE ! The following LGPL license applies to the ldb
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
2009-09-22 04:52:21 +04:00
2004-11-15 14:42:17 +03:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
2007-07-10 06:46:15 +04:00
version 3 of the License , or ( at your option ) any later version .
2004-11-15 14:42:17 +03:00
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
2007-07-10 07:42:26 +04:00
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2004-11-15 14:42:17 +03:00
*/
/*
* Name : ldb
*
* Component : ldb modules core
*
* Description : core modules routines
*
* Author : Simo Sorce
*/
2009-01-30 02:39:30 +03:00
# include "ldb_private.h"
2009-02-24 01:35:49 +03:00
# include "dlinklist.h"
2010-11-01 04:32:18 +03:00
# include "system/dir.h"
2006-03-08 00:02:11 +03:00
2006-10-09 13:56:13 +04:00
static char * ldb_modules_strdup_no_spaces ( TALLOC_CTX * mem_ctx , const char * string )
2005-03-06 18:33:40 +03:00
{
2009-11-06 20:35:17 +03:00
size_t i , len ;
2005-03-06 18:33:40 +03:00
char * trimmed ;
2006-10-09 13:56:13 +04:00
trimmed = talloc_strdup ( mem_ctx , string ) ;
2005-03-06 18:33:40 +03:00
if ( ! trimmed ) {
return NULL ;
}
len = strlen ( trimmed ) ;
for ( i = 0 ; trimmed [ i ] ! = ' \0 ' ; i + + ) {
switch ( trimmed [ i ] ) {
case ' ' :
case ' \t ' :
case ' \n ' :
memmove ( & trimmed [ i ] , & trimmed [ i + 1 ] , len - i - 1 ) ;
break ;
}
}
return trimmed ;
}
/* modules are called in inverse order on the stack.
Lets place them as an admin would think the right order is .
2006-03-02 19:32:53 +03:00
Modules order is important */
2006-08-10 05:51:27 +04:00
const char * * ldb_modules_list_from_string ( struct ldb_context * ldb , TALLOC_CTX * mem_ctx , const char * string )
2005-03-06 18:33:40 +03:00
{
char * * modules = NULL ;
2006-08-04 14:27:14 +04:00
const char * * m ;
2005-03-06 18:33:40 +03:00
char * modstr , * p ;
2009-11-06 20:35:17 +03:00
unsigned int i ;
2005-03-06 18:33:40 +03:00
/* spaces not admitted */
2006-10-09 13:56:13 +04:00
modstr = ldb_modules_strdup_no_spaces ( mem_ctx , string ) ;
2005-03-06 18:33:40 +03:00
if ( ! modstr ) {
2009-07-11 00:44:27 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " Out of Memory in ldb_modules_strdup_no_spaces() " ) ;
2005-03-06 18:33:40 +03:00
return NULL ;
}
2006-08-04 14:27:14 +04:00
modules = talloc_realloc ( mem_ctx , modules , char * , 2 ) ;
2005-03-06 18:33:40 +03:00
if ( ! modules ) {
2009-07-11 00:44:27 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " Out of Memory in ldb_modules_list_from_string() " ) ;
2005-03-06 18:33:40 +03:00
talloc_free ( modstr ) ;
return NULL ;
}
talloc_steal ( modules , modstr ) ;
2009-10-10 02:12:54 +04:00
if ( modstr [ 0 ] = = ' \0 ' ) {
modules [ 0 ] = NULL ;
2014-10-29 13:52:37 +03:00
m = discard_const_p ( const char * , modules ) ;
2009-10-10 02:12:54 +04:00
return m ;
}
2005-03-06 18:33:40 +03:00
i = 0 ;
2006-08-10 05:51:27 +04:00
/* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */
2005-03-06 18:33:40 +03:00
while ( ( p = strrchr ( modstr , ' , ' ) ) ! = NULL ) {
* p = ' \0 ' ;
p + + ;
modules [ i ] = p ;
i + + ;
2006-08-04 14:27:14 +04:00
modules = talloc_realloc ( mem_ctx , modules , char * , i + 2 ) ;
2005-03-06 18:33:40 +03:00
if ( ! modules ) {
2009-07-11 00:44:27 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " Out of Memory in ldb_modules_list_from_string() " ) ;
2005-03-06 18:33:40 +03:00
return NULL ;
}
}
modules [ i ] = modstr ;
modules [ i + 1 ] = NULL ;
2014-10-29 13:52:37 +03:00
m = discard_const_p ( const char * , modules ) ;
2006-08-04 14:27:14 +04:00
return m ;
2005-03-06 18:33:40 +03:00
}
2004-11-15 14:42:17 +03:00
2008-06-28 12:49:49 +04:00
static struct backends_list_entry {
struct ldb_backend_ops * ops ;
struct backends_list_entry * prev , * next ;
} * ldb_backends = NULL ;
2006-03-02 19:32:53 +03:00
static struct ops_list_entry {
const struct ldb_module_ops * ops ;
2009-09-22 04:52:21 +04:00
struct ops_list_entry * next ;
2006-03-02 19:32:53 +03:00
} * registered_modules = NULL ;
2010-11-01 10:41:32 +03:00
static struct backends_list_entry * ldb_find_backend ( const char * url_prefix )
2008-06-28 12:49:49 +04:00
{
struct backends_list_entry * backend ;
for ( backend = ldb_backends ; backend ; backend = backend - > next ) {
2010-11-01 10:41:32 +03:00
if ( strcmp ( backend - > ops - > name , url_prefix ) = = 0 ) {
2010-11-01 08:42:21 +03:00
return backend ;
2008-06-28 12:49:49 +04:00
}
}
return NULL ;
}
/*
2010-11-01 08:42:21 +03:00
register a new ldb backend
if override is true , then override any existing backend for this prefix
2008-06-28 12:49:49 +04:00
*/
2010-11-01 08:42:21 +03:00
int ldb_register_backend ( const char * url_prefix , ldb_connect_fn connectfn , bool override )
2008-06-28 12:49:49 +04:00
{
2010-11-01 08:42:21 +03:00
struct backends_list_entry * be ;
2008-06-28 12:49:49 +04:00
2010-11-01 08:42:21 +03:00
be = ldb_find_backend ( url_prefix ) ;
if ( be ) {
if ( ! override ) {
return LDB_SUCCESS ;
}
} else {
2010-11-01 10:41:32 +03:00
be = talloc_zero ( ldb_backends , struct backends_list_entry ) ;
2010-11-01 08:42:21 +03:00
if ( ! be ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2010-11-01 10:41:32 +03:00
be - > ops = talloc_zero ( be , struct ldb_backend_ops ) ;
if ( ! be - > ops ) {
2010-11-01 08:42:21 +03:00
talloc_free ( be ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
2016-02-05 13:35:38 +03:00
DLIST_ADD_END ( ldb_backends , be ) ;
2008-06-28 12:49:49 +04:00
}
2010-11-01 08:42:21 +03:00
be - > ops - > name = url_prefix ;
be - > ops - > connect_fn = connectfn ;
2008-06-28 12:49:49 +04:00
return LDB_SUCCESS ;
}
/*
Return the ldb module form of a database .
2021-01-29 03:49:02 +03:00
The URL looks something like this :
tdb : //PATH
ldb : //PATH
mdb : //PATH
ldapi : //PATH
PATH ( unadorned PATH defaults to tdb : //)
for a complete list of backends ( including possibly unmaintained ones ) grep
for calls to ldb_register_backend ( ) .
2008-06-28 12:49:49 +04:00
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 .
*/
2010-11-02 02:40:52 +03:00
int ldb_module_connect_backend ( struct ldb_context * ldb ,
const char * url ,
const char * options [ ] ,
struct ldb_module * * backend_module )
2008-06-28 12:49:49 +04:00
{
int ret ;
char * backend ;
2010-11-01 08:42:21 +03:00
struct backends_list_entry * be ;
2022-04-09 09:15:54 +03:00
char * colon = NULL ;
2008-06-28 12:49:49 +04:00
2022-04-09 09:15:54 +03:00
colon = strchr ( url , ' : ' ) ;
if ( colon ! = NULL ) {
backend = talloc_strndup ( ldb , url , colon - url ) ;
2008-06-28 12:49:49 +04:00
} else {
/* Default to tdb */
backend = talloc_strdup ( ldb , " tdb " ) ;
}
2011-04-04 12:26:47 +04:00
if ( backend = = NULL ) {
return ldb_oom ( ldb ) ;
}
2008-06-28 12:49:49 +04:00
2010-11-01 08:42:21 +03:00
be = ldb_find_backend ( backend ) ;
2008-06-28 12:49:49 +04:00
talloc_free ( backend ) ;
2010-11-01 08:42:21 +03:00
if ( be = = NULL ) {
2008-06-28 12:49:49 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL ,
2010-11-02 02:58:49 +03:00
" Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH? " , url ) ;
2008-06-28 12:49:49 +04:00
return LDB_ERR_OTHER ;
}
2010-11-01 08:42:21 +03:00
ret = be - > ops - > connect_fn ( ldb , url , ldb - > flags , options , backend_module ) ;
2008-06-28 12:49:49 +04:00
if ( ret ! = LDB_SUCCESS ) {
ldb_debug ( ldb , LDB_DEBUG_ERROR ,
2011-10-19 03:45:28 +04:00
" Failed to connect to '%s' with backend '%s': %s " , url , be - > ops - > name , ldb_errstring ( ldb ) ) ;
2008-06-28 12:49:49 +04:00
return ret ;
}
return ret ;
}
2008-02-20 04:57:07 +03:00
2010-11-01 10:41:32 +03:00
static struct ldb_hooks {
struct ldb_hooks * next , * prev ;
ldb_hook_fn hook_fn ;
} * ldb_hooks ;
/*
register a ldb hook function
*/
int ldb_register_hook ( ldb_hook_fn hook_fn )
{
struct ldb_hooks * lc ;
lc = talloc_zero ( ldb_hooks , struct ldb_hooks ) ;
if ( lc = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
lc - > hook_fn = hook_fn ;
2016-02-05 13:35:38 +03:00
DLIST_ADD_END ( ldb_hooks , lc ) ;
2010-11-01 10:41:32 +03:00
return LDB_SUCCESS ;
}
/*
call ldb hooks of a given type
*/
int ldb_modules_hook ( struct ldb_context * ldb , enum ldb_module_hook_type t )
{
struct ldb_hooks * lc ;
for ( lc = ldb_hooks ; lc ; lc = lc - > next ) {
int ret = lc - > hook_fn ( ldb , t ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
return LDB_SUCCESS ;
}
2006-03-02 19:32:53 +03:00
static const struct ldb_module_ops * ldb_find_module_ops ( const char * name )
{
struct ops_list_entry * e ;
2009-09-22 04:52:21 +04:00
2006-03-02 19:32:53 +03:00
for ( e = registered_modules ; e ; e = e - > next ) {
2009-09-22 04:52:21 +04:00
if ( strcmp ( e - > ops - > name , name ) = = 0 )
2006-03-02 19:32:53 +03:00
return e - > ops ;
}
return NULL ;
}
int ldb_register_module ( const struct ldb_module_ops * ops )
{
2010-11-08 02:58:28 +03:00
struct ops_list_entry * entry ;
2006-03-02 19:32:53 +03:00
if ( ldb_find_module_ops ( ops - > name ) ! = NULL )
2010-11-08 02:58:28 +03:00
return LDB_ERR_ENTRY_ALREADY_EXISTS ;
2006-03-02 19:32:53 +03:00
2017-07-24 22:11:03 +03:00
/*
* ldb modules are not ( yet ) unloaded and
* are only loaded once ( the above check
* makes sure of this ) . Allocate off the NULL
* context . We never want this to be freed
* until process shutdown . If eventually we
* want to unload ldb modules we can add a
* deregister function that walks and
* frees the list .
*/
entry = talloc ( NULL , struct ops_list_entry ) ;
2011-04-04 12:43:39 +04:00
if ( entry = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-03-02 19:32:53 +03:00
entry - > ops = ops ;
entry - > next = registered_modules ;
registered_modules = entry ;
2011-04-04 12:43:39 +04:00
return LDB_SUCCESS ;
2006-03-02 19:32:53 +03:00
}
2010-11-02 02:40:52 +03:00
/*
load a list of modules
*/
int ldb_module_load_list ( struct ldb_context * ldb , const char * * module_list ,
struct ldb_module * backend , struct ldb_module * * out )
2006-08-10 04:52:56 +04:00
{
struct ldb_module * module ;
2009-11-06 20:35:17 +03:00
unsigned int i ;
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
module = backend ;
2009-10-12 13:11:03 +04:00
for ( i = 0 ; module_list & & module_list [ i ] ! = NULL ; i + + ) {
2006-08-10 04:52:56 +04:00
struct ldb_module * current ;
const struct ldb_module_ops * ops ;
2008-11-06 03:13:37 +03:00
if ( strcmp ( module_list [ i ] , " " ) = = 0 ) {
continue ;
}
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
ops = ldb_find_module_ops ( module_list [ i ] ) ;
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
if ( ops = = NULL ) {
2010-11-02 02:58:49 +03:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH? " ,
2006-08-10 04:52:56 +04:00
module_list [ i ] ) ;
2010-11-18 16:01:15 +03:00
return LDB_ERR_OPERATIONS_ERROR ;
2006-08-10 04:52:56 +04:00
}
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
current = talloc_zero ( ldb , struct ldb_module ) ;
if ( current = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-10-17 05:21:02 +04:00
talloc_set_name ( current , " ldb_module: %s " , module_list [ i ] ) ;
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
current - > ldb = ldb ;
current - > ops = ops ;
2009-09-22 04:52:21 +04:00
2006-08-10 04:52:56 +04:00
DLIST_ADD ( module , current ) ;
}
* out = module ;
return LDB_SUCCESS ;
}
2010-11-02 02:40:52 +03:00
/*
initialise a chain of modules
*/
int ldb_module_init_chain ( struct ldb_context * ldb , struct ldb_module * module )
2006-08-10 04:52:56 +04:00
{
2009-09-22 04:52:21 +04:00
while ( module & & module - > ops - > init_context = = NULL )
2006-08-10 04:52:56 +04:00
module = module - > next ;
2007-12-05 03:25:07 +03:00
/* init is different in that it is not an error if modules
* do not require initialization */
if ( module ) {
int ret = module - > ops - > init_context ( module ) ;
if ( ret ! = LDB_SUCCESS ) {
2010-11-05 06:10:30 +03:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " module %s initialization failed : %s " ,
module - > ops - > name , ldb_strerror ( ret ) ) ;
2007-12-05 03:25:07 +03:00
return ret ;
}
2006-08-10 04:52:56 +04:00
}
return LDB_SUCCESS ;
}
2004-11-15 14:42:17 +03:00
int ldb_load_modules ( struct ldb_context * ldb , const char * options [ ] )
{
2010-07-06 09:35:16 +04:00
const char * modules_string ;
2006-08-04 14:27:14 +04:00
const char * * modules = NULL ;
2006-08-10 04:52:56 +04:00
int ret ;
2006-08-04 14:27:14 +04:00
TALLOC_CTX * mem_ctx = talloc_new ( ldb ) ;
if ( ! mem_ctx ) {
2011-04-04 12:43:39 +04:00
return ldb_oom ( ldb ) ;
2006-08-04 14:27:14 +04:00
}
2004-11-15 14:42:17 +03:00
/* find out which modules we are requested to activate */
2005-03-06 18:33:40 +03:00
/* check if we have a custom module list passd as ldb option */
2004-11-15 14:42:17 +03:00
if ( options ) {
2010-07-06 09:35:16 +04:00
modules_string = ldb_options_find ( ldb , options , " modules " ) ;
if ( modules_string ) {
modules = ldb_modules_list_from_string ( ldb , mem_ctx , modules_string ) ;
2004-11-15 14:42:17 +03:00
}
}
2006-03-02 19:32:53 +03:00
/* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
2009-09-22 04:52:21 +04:00
if ( ( modules = = NULL ) & & ( strcmp ( " ldap " , ldb - > modules - > ops - > name ) ! = 0 ) ) {
2005-02-27 14:35:47 +03:00
const char * const attrs [ ] = { " @LIST " , NULL } ;
2006-08-04 16:05:46 +04:00
struct ldb_result * res = NULL ;
struct ldb_dn * mods_dn ;
2004-11-15 14:42:17 +03:00
2006-11-22 03:59:34 +03:00
mods_dn = ldb_dn_new ( mem_ctx , ldb , " @MODULES " ) ;
2006-08-04 16:05:46 +04:00
if ( mods_dn = = NULL ) {
2006-08-04 14:27:14 +04:00
talloc_free ( mem_ctx ) ;
2011-04-04 12:43:39 +04:00
return ldb_oom ( ldb ) ;
2005-08-18 19:02:01 +04:00
}
2008-09-23 22:30:06 +04:00
ret = ldb_search ( ldb , mods_dn , & res , mods_dn , LDB_SCOPE_BASE , attrs , " @LIST=* " ) ;
2009-09-22 04:52:21 +04:00
2007-11-13 06:32:36 +03:00
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
ldb_debug ( ldb , LDB_DEBUG_TRACE , " no modules required by the db " ) ;
} else if ( ret ! = LDB_SUCCESS ) {
2009-07-11 00:44:27 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " ldb error (%s) occurred searching for modules, bailing out " , ldb_errstring ( ldb ) ) ;
2007-11-06 05:46:57 +03:00
talloc_free ( mem_ctx ) ;
2007-11-15 07:54:51 +03:00
return ret ;
2004-11-15 14:42:17 +03:00
} else {
2007-11-15 07:54:51 +03:00
const char * module_list ;
if ( res - > count = = 0 ) {
2007-11-13 06:32:36 +03:00
ldb_debug ( ldb , LDB_DEBUG_TRACE , " no modules required by the db " ) ;
2007-11-15 07:54:51 +03:00
} else if ( res - > count > 1 ) {
2011-04-08 10:29:51 +04:00
ldb_debug ( ldb , LDB_DEBUG_FATAL , " Too many records found (%u), bailing out " , res - > count ) ;
2007-11-15 07:54:51 +03:00
talloc_free ( mem_ctx ) ;
2011-04-04 12:43:39 +04:00
return LDB_ERR_OPERATIONS_ERROR ;
2007-11-13 06:32:36 +03:00
} else {
2007-11-15 07:54:51 +03:00
module_list = ldb_msg_find_attr_as_string ( res - > msgs [ 0 ] , " @LIST " , NULL ) ;
if ( ! module_list ) {
ldb_debug ( ldb , LDB_DEBUG_TRACE , " no modules required by the db " ) ;
2007-11-13 06:32:36 +03:00
}
modules = ldb_modules_list_from_string ( ldb , mem_ctx ,
2007-11-15 07:54:51 +03:00
module_list ) ;
2004-11-15 14:42:17 +03:00
}
}
2006-08-04 16:05:46 +04:00
talloc_free ( mods_dn ) ;
2004-11-15 14:42:17 +03:00
}
2006-03-07 00:58:07 +03:00
if ( modules ! = NULL ) {
2010-11-02 02:40:52 +03:00
ret = ldb_module_load_list ( ldb , modules , ldb - > modules , & ldb - > modules ) ;
2006-08-10 04:52:56 +04:00
if ( ret ! = LDB_SUCCESS ) {
2007-10-31 01:35:04 +03:00
talloc_free ( mem_ctx ) ;
2006-08-10 04:52:56 +04:00
return ret ;
}
2006-03-07 00:58:07 +03:00
} else {
2007-08-20 04:22:08 +04:00
ldb_debug ( ldb , LDB_DEBUG_TRACE , " No modules specified for this database " ) ;
2004-11-15 14:42:17 +03:00
}
2010-11-02 02:40:52 +03:00
ret = ldb_module_init_chain ( ldb , ldb - > modules ) ;
2007-10-31 01:35:04 +03:00
talloc_free ( mem_ctx ) ;
return ret ;
2004-11-15 14:42:17 +03:00
}
2005-10-06 10:57:09 +04:00
/*
by using this we allow ldb modules to only implement the functions they care about ,
which makes writing a module simpler , and makes it more likely to keep working
when ldb is extended
*/
2009-09-03 12:29:58 +04:00
# define FIND_OP_NOERR(module, op) do { \
2005-10-06 10:57:09 +04:00
module = module - > next ; \
while ( module & & module - > ops - > op = = NULL ) module = module - > next ; \
2009-10-27 02:43:51 +03:00
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) { \
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE , " ldb_trace_next_request: (%s)-> " # op , \
module - > ops - > name ) ; \
} \
2009-09-03 12:29:58 +04:00
} while ( 0 )
# define FIND_OP(module, op) do { \
struct ldb_context * ldb = module - > ldb ; \
FIND_OP_NOERR ( module , op ) ; \
2006-07-10 12:31:47 +04:00
if ( module = = NULL ) { \
2006-08-13 11:33:57 +04:00
ldb_asprintf_errstring ( ldb , " Unable to find backend operation for " # op ) ; \
2006-07-10 12:31:47 +04:00
return LDB_ERR_OPERATIONS_ERROR ; \
} \
2005-10-06 10:57:09 +04:00
} while ( 0 )
2009-01-30 02:39:30 +03:00
struct ldb_module * ldb_module_new ( TALLOC_CTX * memctx ,
struct ldb_context * ldb ,
const char * module_name ,
const struct ldb_module_ops * ops )
{
struct ldb_module * module ;
module = talloc ( memctx , struct ldb_module ) ;
if ( ! module ) {
ldb_oom ( ldb ) ;
return NULL ;
}
talloc_set_name_const ( module , module_name ) ;
module - > ldb = ldb ;
module - > prev = module - > next = NULL ;
module - > ops = ops ;
return module ;
}
2009-01-30 18:18:52 +03:00
const char * ldb_module_get_name ( struct ldb_module * module )
{
return module - > ops - > name ;
}
2009-01-30 02:39:30 +03:00
struct ldb_context * ldb_module_get_ctx ( struct ldb_module * module )
{
return module - > ldb ;
}
2009-12-21 13:03:11 +03:00
const struct ldb_module_ops * ldb_module_get_ops ( struct ldb_module * module )
{
return module - > ops ;
}
2009-01-30 02:39:30 +03:00
void * ldb_module_get_private ( struct ldb_module * module )
{
return module - > private_data ;
}
void ldb_module_set_private ( struct ldb_module * module , void * private_data )
{
module - > private_data = private_data ;
}
2004-11-15 14:42:17 +03:00
/*
helper functions to call the next module in chain
*/
2006-05-29 05:30:02 +04:00
2005-11-08 03:11:45 +03:00
int ldb_next_request ( struct ldb_module * module , struct ldb_request * request )
2005-10-06 09:24:46 +04:00
{
2007-03-08 06:32:28 +03:00
int ret ;
2008-09-12 02:33:16 +04:00
if ( request - > callback = = NULL ) {
ldb_set_errstring ( module - > ldb , " Requests MUST define callbacks " ) ;
return LDB_ERR_UNWILLING_TO_PERFORM ;
}
2009-09-22 05:15:19 +04:00
request - > handle - > nesting + + ;
2006-05-29 05:30:02 +04:00
switch ( request - > operation ) {
2006-05-30 04:33:52 +04:00
case LDB_SEARCH :
2006-05-29 05:30:02 +04:00
FIND_OP ( module , search ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > search ( module , request ) ;
break ;
2006-05-30 04:33:52 +04:00
case LDB_ADD :
2006-05-29 05:30:02 +04:00
FIND_OP ( module , add ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > add ( module , request ) ;
break ;
2006-05-30 04:33:52 +04:00
case LDB_MODIFY :
2006-05-29 05:30:02 +04:00
FIND_OP ( module , modify ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > modify ( module , request ) ;
break ;
2006-05-30 04:33:52 +04:00
case LDB_DELETE :
2006-05-29 05:30:02 +04:00
FIND_OP ( module , del ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > del ( module , request ) ;
break ;
2006-05-30 04:33:52 +04:00
case LDB_RENAME :
2006-05-29 05:30:02 +04:00
FIND_OP ( module , rename ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > rename ( module , request ) ;
break ;
2007-01-06 13:21:32 +03:00
case LDB_EXTENDED :
FIND_OP ( module , extended ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > extended ( module , request ) ;
break ;
2006-05-29 05:30:02 +04:00
default :
FIND_OP ( module , request ) ;
2007-03-08 06:32:28 +03:00
ret = module - > ops - > request ( module , request ) ;
break ;
}
2009-09-22 05:15:19 +04:00
request - > handle - > nesting - - ;
2007-03-08 06:32:28 +03:00
if ( ret = = LDB_SUCCESS ) {
return ret ;
2006-05-29 05:30:02 +04:00
}
2007-03-08 06:32:28 +03:00
if ( ! ldb_errstring ( module - > ldb ) ) {
2013-09-06 07:37:30 +04:00
const char * op ;
switch ( request - > operation ) {
case LDB_SEARCH :
op = " LDB_SEARCH " ;
break ;
case LDB_ADD :
op = " LDB_ADD " ;
break ;
case LDB_MODIFY :
op = " LDB_MODIFY " ;
break ;
case LDB_DELETE :
op = " LDB_DELETE " ;
break ;
case LDB_RENAME :
op = " LDB_RENAME " ;
break ;
case LDB_EXTENDED :
op = " LDB_EXTENDED " ;
break ;
default :
op = " request " ;
break ;
}
2007-03-08 06:32:28 +03:00
/* Set a default error string, to place the blame somewhere */
2013-09-06 07:37:30 +04:00
ldb_asprintf_errstring ( module - > ldb , " error in module %s: %s during %s (%d) " , module - > ops - > name , ldb_strerror ( ret ) , op , ret ) ;
2007-03-08 06:32:28 +03:00
}
2009-09-04 11:22:20 +04:00
if ( ! ( request - > handle - > flags & LDB_HANDLE_FLAG_DONE_CALLED ) ) {
/* It is _extremely_ common that a module returns a
* failure without calling ldb_module_done ( ) , but that
* guarantees we will end up hanging in
* ldb_wait ( ) . This fixes it without having to rewrite
* all our modules , and leaves us one less sharp
2009-09-22 04:52:21 +04:00
* corner for module developers to cut themselves on
2009-09-04 11:22:20 +04:00
*/
2009-12-29 03:40:30 +03:00
ret = ldb_module_done ( request , NULL , NULL , ret ) ;
2009-09-04 11:22:20 +04:00
}
2007-03-08 06:32:28 +03:00
return ret ;
2004-11-15 14:42:17 +03:00
}
2006-03-02 19:32:53 +03:00
int ldb_next_init ( struct ldb_module * module )
2006-01-06 19:12:45 +03:00
{
2006-03-02 19:32:53 +03:00
module = module - > next ;
2010-11-02 02:40:52 +03:00
return ldb_module_init_chain ( module - > ldb , module ) ;
2006-01-06 19:12:45 +03:00
}
2005-09-17 23:25:50 +04:00
int ldb_next_start_trans ( struct ldb_module * module )
2004-11-21 18:51:54 +03:00
{
2009-10-27 02:43:51 +03:00
int ret ;
2005-10-06 10:57:09 +04:00
FIND_OP ( module , start_transaction ) ;
2009-10-27 02:43:51 +03:00
ret = module - > ops - > start_transaction ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb , " start_trans error in module %s: %s (%d) " , module - > ops - > name , ldb_strerror ( ret ) , ret ) ;
}
2024-09-25 10:19:17 +03:00
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE , " ldb_next_start_trans error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
2009-10-27 02:43:51 +03:00
}
return ret ;
2004-11-21 18:51:54 +03:00
}
2005-09-24 19:42:15 +04:00
int ldb_next_end_trans ( struct ldb_module * module )
2004-11-21 18:51:54 +03:00
{
2009-10-27 02:43:51 +03:00
int ret ;
2005-10-06 10:57:09 +04:00
FIND_OP ( module , end_transaction ) ;
2009-10-27 02:43:51 +03:00
ret = module - > ops - > end_transaction ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb , " end_trans error in module %s: %s (%d) " , module - > ops - > name , ldb_strerror ( ret ) , ret ) ;
}
2024-09-25 10:19:17 +03:00
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE , " ldb_next_end_trans error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
2009-10-27 02:43:51 +03:00
}
return ret ;
2005-09-24 19:42:15 +04:00
}
2017-06-15 03:10:51 +03:00
int ldb_next_read_lock ( struct ldb_module * module )
{
int ret ;
FIND_OP ( module , read_lock ) ;
ret = module - > ops - > read_lock ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb ,
" read_lock error in module %s: %s (%d) " ,
module - > ops - > name , ldb_strerror ( ret ) ,
ret ) ;
}
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE ,
" ldb_next_read_lock error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
}
return ret ;
}
int ldb_next_read_unlock ( struct ldb_module * module )
{
int ret ;
FIND_OP ( module , read_unlock ) ;
ret = module - > ops - > read_unlock ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb ,
" read_unlock error in module %s: %s (%d) " ,
module - > ops - > name , ldb_strerror ( ret ) ,
ret ) ;
}
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE ,
" ldb_next_read_unlock error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
}
return ret ;
}
2009-09-03 12:29:58 +04:00
int ldb_next_prepare_commit ( struct ldb_module * module )
{
2009-10-27 02:43:51 +03:00
int ret ;
2009-09-03 12:29:58 +04:00
FIND_OP_NOERR ( module , prepare_commit ) ;
if ( module = = NULL ) {
/* we are allowed to have no prepare commit in
backends */
return LDB_SUCCESS ;
}
2009-10-27 02:43:51 +03:00
ret = module - > ops - > prepare_commit ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb , " prepare_commit error in module %s: %s (%d) " , module - > ops - > name , ldb_strerror ( ret ) , ret ) ;
}
2024-09-25 10:19:17 +03:00
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE , " ldb_next_prepare_commit error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
2009-10-27 02:43:51 +03:00
}
return ret ;
2009-09-03 12:29:58 +04:00
}
2005-09-24 19:42:15 +04:00
int ldb_next_del_trans ( struct ldb_module * module )
{
2009-10-27 02:43:51 +03:00
int ret ;
2005-10-06 10:57:09 +04:00
FIND_OP ( module , del_transaction ) ;
2009-10-27 02:43:51 +03:00
ret = module - > ops - > del_transaction ( module ) ;
if ( ret = = LDB_SUCCESS ) {
return ret ;
}
if ( ! ldb_errstring ( module - > ldb ) ) {
/* Set a default error string, to place the blame somewhere */
ldb_asprintf_errstring ( module - > ldb , " del_trans error in module %s: %s (%d) " , module - > ops - > name , ldb_strerror ( ret ) , ret ) ;
}
2024-09-25 10:19:17 +03:00
if ( ( module & & module - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) ) {
ldb_debug ( module - > ldb , LDB_DEBUG_TRACE , " ldb_next_del_trans error: %s " ,
ldb_errstring ( module - > ldb ) ) ;
2009-10-27 02:43:51 +03:00
}
return ret ;
2004-11-21 18:51:54 +03:00
}
2008-06-28 12:49:49 +04:00
2008-09-12 02:33:16 +04:00
/* calls the request callback to send an entry
*
* params :
* req : the original request passed to your module
* msg : reply message ( must be a talloc pointer , and it will be stolen
* on the ldb_reply that is sent to the callback )
2008-12-16 10:59:05 +03:00
* ctrls : controls to send in the reply ( must be a talloc pointer , and it will be stolen
* on the ldb_reply that is sent to the callback )
2008-09-12 02:33:16 +04:00
*/
int ldb_module_send_entry ( struct ldb_request * req ,
2008-12-16 10:59:05 +03:00
struct ldb_message * msg ,
struct ldb_control * * ctrls )
2008-09-12 02:33:16 +04:00
{
struct ldb_reply * ares ;
ares = talloc_zero ( req , struct ldb_reply ) ;
if ( ! ares ) {
ldb_oom ( req - > handle - > ldb ) ;
req - > callback ( req , NULL ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
ares - > type = LDB_REPLY_ENTRY ;
ares - > message = talloc_steal ( ares , msg ) ;
2008-12-16 10:59:05 +03:00
ares - > controls = talloc_steal ( ares , ctrls ) ;
2008-09-12 02:33:16 +04:00
ares - > error = LDB_SUCCESS ;
2009-09-22 05:15:19 +04:00
if ( ( req - > handle - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) & &
req - > handle - > nesting = = 0 ) {
2009-09-22 02:24:14 +04:00
char * s ;
2012-08-29 05:29:44 +04:00
struct ldb_ldif ldif ;
2024-09-25 10:19:17 +03:00
2012-08-29 05:29:44 +04:00
ldif . changetype = LDB_CHANGETYPE_NONE ;
ldif . msg = discard_const_p ( struct ldb_message , msg ) ;
2009-09-22 04:52:21 +04:00
ldb_debug_add ( req - > handle - > ldb , " ldb_trace_response: ENTRY \n " ) ;
2012-08-29 05:29:44 +04:00
2024-09-25 10:19:17 +03:00
/*
2012-08-29 05:29:44 +04:00
* The choice to call
* ldb_ldif_write_redacted_trace_string ( ) is CRITICAL
* for security . It ensures that we do not output
2024-09-25 10:19:17 +03:00
* passwords into debug logs
2012-08-29 05:29:44 +04:00
*/
s = ldb_ldif_write_redacted_trace_string ( req - > handle - > ldb , msg , & ldif ) ;
2009-09-22 04:52:21 +04:00
ldb_debug_add ( req - > handle - > ldb , " %s \n " , s ) ;
talloc_free ( s ) ;
ldb_debug_end ( req - > handle - > ldb , LDB_DEBUG_TRACE ) ;
2009-09-22 02:24:14 +04:00
}
2008-09-12 02:33:16 +04:00
return req - > callback ( req , ares ) ;
}
2023-10-16 06:08:04 +03:00
/* calls the request callback to send a referral
2008-09-12 02:33:16 +04:00
*
* params :
* req : the original request passed to your module
2011-10-21 00:29:43 +04:00
* ref : referral string ( must be a talloc pointer , steal )
2008-09-12 02:33:16 +04:00
*/
int ldb_module_send_referral ( struct ldb_request * req ,
char * ref )
{
struct ldb_reply * ares ;
ares = talloc_zero ( req , struct ldb_reply ) ;
if ( ! ares ) {
ldb_oom ( req - > handle - > ldb ) ;
req - > callback ( req , NULL ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
ares - > type = LDB_REPLY_REFERRAL ;
ares - > referral = talloc_steal ( ares , ref ) ;
ares - > error = LDB_SUCCESS ;
2009-09-22 05:15:19 +04:00
if ( ( req - > handle - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) & &
req - > handle - > nesting = = 0 ) {
2009-09-22 04:52:21 +04:00
ldb_debug_add ( req - > handle - > ldb , " ldb_trace_response: REFERRAL \n " ) ;
ldb_debug_add ( req - > handle - > ldb , " ref: %s \n " , ref ) ;
ldb_debug_end ( req - > handle - > ldb , LDB_DEBUG_TRACE ) ;
2009-09-22 02:24:14 +04:00
}
2008-09-12 02:33:16 +04:00
return req - > callback ( req , ares ) ;
}
/* calls the original request callback
*
* params :
* req : the original request passed to your module
* ctrls : controls to send in the reply ( must be a talloc pointer , steal )
* response : results for extended request ( steal )
2010-02-21 09:22:45 +03:00
* error : LDB_SUCCESS for a successful return
2008-09-12 02:33:16 +04:00
* any other ldb error otherwise
*/
int ldb_module_done ( struct ldb_request * req ,
struct ldb_control * * ctrls ,
struct ldb_extended * response ,
int error )
{
struct ldb_reply * ares ;
ares = talloc_zero ( req , struct ldb_reply ) ;
if ( ! ares ) {
ldb_oom ( req - > handle - > ldb ) ;
req - > callback ( req , NULL ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
ares - > type = LDB_REPLY_DONE ;
ares - > controls = talloc_steal ( ares , ctrls ) ;
ares - > response = talloc_steal ( ares , response ) ;
ares - > error = error ;
2009-09-04 11:22:20 +04:00
req - > handle - > flags | = LDB_HANDLE_FLAG_DONE_CALLED ;
2009-09-22 05:15:19 +04:00
if ( ( req - > handle - > ldb - > flags & LDB_FLG_ENABLE_TRACING ) & &
req - > handle - > nesting = = 0 ) {
2009-09-22 04:52:21 +04:00
ldb_debug_add ( req - > handle - > ldb , " ldb_trace_response: DONE \n " ) ;
2011-04-08 10:29:51 +04:00
ldb_debug_add ( req - > handle - > ldb , " error: %d \n " , error ) ;
2009-09-22 02:24:14 +04:00
if ( ldb_errstring ( req - > handle - > ldb ) ) {
2009-09-22 04:52:21 +04:00
ldb_debug_add ( req - > handle - > ldb , " msg: %s \n " ,
2009-09-22 02:24:14 +04:00
ldb_errstring ( req - > handle - > ldb ) ) ;
}
2009-09-22 04:52:21 +04:00
ldb_debug_end ( req - > handle - > ldb , LDB_DEBUG_TRACE ) ;
2009-09-22 02:24:14 +04:00
}
2009-12-30 13:36:31 +03:00
return req - > callback ( req , ares ) ;
2008-09-12 02:33:16 +04:00
}
/* to be used *only* in modules init functions.
2010-10-04 20:57:00 +04:00
* this function is synchronous and will register
2008-09-12 02:33:16 +04:00
* the requested OID in the rootdse module if present
* otherwise it will return an error */
int ldb_mod_register_control ( struct ldb_module * module , const char * oid )
{
struct ldb_request * req ;
int ret ;
req = talloc_zero ( module , struct ldb_request ) ;
if ( req = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
req - > operation = LDB_REQ_REGISTER_CONTROL ;
req - > op . reg_control . oid = oid ;
req - > callback = ldb_op_default_callback ;
ldb_set_timeout ( module - > ldb , req , 0 ) ;
req - > handle = ldb_handle_new ( req , module - > ldb ) ;
if ( req - > handle = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
ret = ldb_request ( module - > ldb , req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
talloc_free ( req ) ;
return ret ;
}
2010-11-01 04:32:18 +03:00
static int ldb_modules_load_dir ( const char * modules_dir , const char * version ) ;
/*
load one module . A static list of loaded module inode numbers is
used to prevent a module being loaded twice
dlopen ( ) is used on the module , and dlsym ( ) is then used to look for
a ldb_init_module ( ) function . If present , that function is called
with the ldb version number as an argument .
The ldb_init_module ( ) function will typically call
ldb_register_module ( ) and ldb_register_backend ( ) to register a
module or backend , but it may also be used to register command line
handling functions , ldif handlers or any other local
2023-10-16 06:08:04 +03:00
modifications .
2010-11-01 04:32:18 +03:00
The ldb_init_module ( ) function does not get a ldb_context passed in ,
as modules will be used for multiple ldb context handles . The call
from the first ldb_init ( ) is just a convenient way to ensure it is
called early enough .
*/
2010-11-04 12:13:17 +03:00
static int ldb_modules_load_path ( const char * path , const char * version )
2010-11-01 04:32:18 +03:00
{
void * handle ;
int ( * init_fn ) ( const char * ) ;
int ret ;
struct stat st ;
static struct loaded {
struct loaded * next , * prev ;
ino_t st_ino ;
dev_t st_dev ;
} * loaded ;
struct loaded * le ;
2010-12-08 01:41:25 +03:00
int dlopen_flags ;
2016-11-21 23:41:51 +03:00
# ifdef RTLD_DEEPBIND
2024-09-25 10:19:44 +03:00
bool deepbind_enabled = ( getenv ( " LDB_MODULES_ENABLE_DEEPBIND " ) ! = NULL ) ;
2016-11-21 23:41:51 +03:00
# endif
2010-11-01 04:32:18 +03:00
ret = stat ( path , & st ) ;
if ( ret ! = 0 ) {
fprintf ( stderr , " ldb: unable to stat module %s : %s \n " , path , strerror ( errno ) ) ;
return LDB_ERR_UNAVAILABLE ;
}
for ( le = loaded ; le ; le = le - > next ) {
if ( le - > st_ino = = st . st_ino & &
le - > st_dev = = st . st_dev ) {
/* its already loaded */
return LDB_SUCCESS ;
}
}
le = talloc ( loaded , struct loaded ) ;
if ( le = = NULL ) {
fprintf ( stderr , " ldb: unable to allocated loaded entry \n " ) ;
return LDB_ERR_UNAVAILABLE ;
}
le - > st_ino = st . st_ino ;
le - > st_dev = st . st_dev ;
2016-02-05 13:35:38 +03:00
DLIST_ADD_END ( loaded , le ) ;
2010-11-01 04:32:18 +03:00
/* if it is a directory, recurse */
if ( S_ISDIR ( st . st_mode ) ) {
return ldb_modules_load_dir ( path , version ) ;
}
2010-12-08 01:41:25 +03:00
dlopen_flags = RTLD_NOW ;
# ifdef RTLD_DEEPBIND
2014-03-04 16:50:41 +04:00
/*
2024-09-25 10:19:44 +03:00
* On systems where e . g . different kerberos libraries are used , like a
* mix of Heimdal and MIT Kerberos , LDB_MODULES_ENABLE_DEEPBIND should
* be set to avoid issues .
2014-03-04 16:50:41 +04:00
*
2024-09-25 10:19:44 +03:00
* By default Linux distributions only have one Kerberos library .
*/
2014-03-04 16:50:41 +04:00
if ( deepbind_enabled ) {
dlopen_flags | = RTLD_DEEPBIND ;
}
2010-12-08 01:41:25 +03:00
# endif
handle = dlopen ( path , dlopen_flags ) ;
2010-11-01 04:32:18 +03:00
if ( handle = = NULL ) {
2010-11-01 10:41:32 +03:00
fprintf ( stderr , " ldb: unable to dlopen %s : %s \n " , path , dlerror ( ) ) ;
2010-11-01 04:32:18 +03:00
return LDB_SUCCESS ;
}
init_fn = dlsym ( handle , " ldb_init_module " ) ;
if ( init_fn = = NULL ) {
/* ignore it, it could be an old-style
* module . Once we ' ve converted all modules we
* could consider this an error */
dlclose ( handle ) ;
return LDB_SUCCESS ;
}
ret = init_fn ( version ) ;
2010-11-08 07:46:09 +03:00
if ( ret = = LDB_ERR_ENTRY_ALREADY_EXISTS ) {
/* the module is already registered - ignore this, as
* it can happen if LDB_MODULES_PATH points at both
* the build and install directory
*/
ret = LDB_SUCCESS ;
}
2010-11-01 04:32:18 +03:00
return ret ;
}
2010-11-03 12:37:08 +03:00
static int qsort_string ( const char * * s1 , const char * * s2 )
{
return strcmp ( * s1 , * s2 ) ;
}
2010-11-01 04:32:18 +03:00
/*
load all modules from the given ldb modules directory . This is run once
during the first ldb_init ( ) call .
Modules are loaded in alphabetical order to ensure that any module
load ordering dependencies are reproducible . Modules should avoid
relying on load order
*/
static int ldb_modules_load_dir ( const char * modules_dir , const char * version )
{
DIR * dir ;
struct dirent * de ;
const char * * modlist = NULL ;
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
unsigned i , num_modules = 0 ;
dir = opendir ( modules_dir ) ;
if ( dir = = NULL ) {
2010-11-01 08:07:35 +03:00
if ( errno = = ENOENT ) {
talloc_free ( tmp_ctx ) ;
/* we don't have any modules */
return LDB_SUCCESS ;
}
2010-11-01 04:32:18 +03:00
talloc_free ( tmp_ctx ) ;
fprintf ( stderr , " ldb: unable to open modules directory '%s' - %s \n " ,
modules_dir , strerror ( errno ) ) ;
return LDB_ERR_UNAVAILABLE ;
}
while ( ( de = readdir ( dir ) ) ) {
if ( ISDOT ( de - > d_name ) | | ISDOTDOT ( de - > d_name ) )
continue ;
modlist = talloc_realloc ( tmp_ctx , modlist , const char * , num_modules + 1 ) ;
if ( modlist = = NULL ) {
talloc_free ( tmp_ctx ) ;
closedir ( dir ) ;
fprintf ( stderr , " ldb: unable to allocate modules list \n " ) ;
return LDB_ERR_UNAVAILABLE ;
}
modlist [ num_modules ] = talloc_asprintf ( modlist , " %s/%s " , modules_dir , de - > d_name ) ;
if ( modlist [ num_modules ] = = NULL ) {
talloc_free ( tmp_ctx ) ;
closedir ( dir ) ;
fprintf ( stderr , " ldb: unable to allocate module list entry \n " ) ;
return LDB_ERR_UNAVAILABLE ;
}
num_modules + + ;
}
closedir ( dir ) ;
/* sort the directory, so we get consistent load ordering */
2010-11-03 12:37:08 +03:00
TYPESAFE_QSORT ( modlist , num_modules , qsort_string ) ;
2010-11-01 04:32:18 +03:00
for ( i = 0 ; i < num_modules ; i + + ) {
2010-11-04 12:13:17 +03:00
int ret = ldb_modules_load_path ( modlist [ i ] , version ) ;
2010-11-01 04:32:18 +03:00
if ( ret ! = LDB_SUCCESS ) {
2010-11-01 10:41:32 +03:00
fprintf ( stderr , " ldb: failed to initialise module %s : %s \n " ,
2010-11-01 04:32:18 +03:00
modlist [ i ] , ldb_strerror ( ret ) ) ;
talloc_free ( tmp_ctx ) ;
return ret ;
}
}
talloc_free ( tmp_ctx ) ;
return LDB_SUCCESS ;
}
2024-09-25 10:19:17 +03:00
/*
load any additional modules from the given directory
2010-11-01 14:48:16 +03:00
*/
void ldb_set_modules_dir ( struct ldb_context * ldb , const char * path )
{
2018-02-14 04:31:58 +03:00
int ret = ldb_modules_load_dir ( path , LDB_VERSION ) ;
2010-11-01 14:48:16 +03:00
if ( ret ! = LDB_SUCCESS ) {
ldb_asprintf_errstring ( ldb , " Failed to load modules from: %s \n " , path ) ;
}
}
2010-11-01 07:00:11 +03:00
/*
load all modules static ( builtin ) modules
*/
static int ldb_modules_load_static ( const char * version )
{
static bool initialised ;
# define _MODULE_PROTO(init) extern int init(const char *);
STATIC_ldb_MODULES_PROTO ;
const ldb_module_init_fn static_init_functions [ ] = { STATIC_ldb_MODULES } ;
unsigned i ;
if ( initialised ) {
return LDB_SUCCESS ;
}
initialised = true ;
for ( i = 0 ; static_init_functions [ i ] ; i + + ) {
int ret = static_init_functions [ i ] ( version ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
return LDB_SUCCESS ;
}
2010-11-01 04:32:18 +03:00
/*
load all modules from the given ldb modules path , colon
separated .
modules are loaded recursively for all subdirectories in the paths
*/
int ldb_modules_load ( const char * modules_path , const char * version )
{
char * tok , * path , * tok_ptr = NULL ;
2010-11-01 07:00:11 +03:00
int ret ;
ret = ldb_modules_load_static ( version ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2010-11-01 04:32:18 +03:00
path = talloc_strdup ( NULL , modules_path ) ;
if ( path = = NULL ) {
2010-11-01 10:41:32 +03:00
fprintf ( stderr , " ldb: failed to allocate modules_path \n " ) ;
2010-11-01 04:32:18 +03:00
return LDB_ERR_UNAVAILABLE ;
}
for ( tok = strtok_r ( path , " : " , & tok_ptr ) ;
tok ;
tok = strtok_r ( NULL , " : " , & tok_ptr ) ) {
2010-11-04 12:13:17 +03:00
ret = ldb_modules_load_path ( tok , version ) ;
2010-11-01 04:32:18 +03:00
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( path ) ;
return ret ;
}
}
talloc_free ( path ) ;
return LDB_SUCCESS ;
}
2010-11-02 02:40:52 +03:00
/*
return a string representation of the calling chain for the given
ldb request
*/
char * ldb_module_call_chain ( struct ldb_request * req , TALLOC_CTX * mem_ctx )
{
char * ret ;
2011-04-08 10:30:41 +04:00
unsigned int i = 0 ;
2010-11-02 02:40:52 +03:00
ret = talloc_strdup ( mem_ctx , " " ) ;
if ( ret = = NULL ) {
return NULL ;
}
while ( req & & req - > handle ) {
2022-11-28 13:07:25 +03:00
talloc_asprintf_addbuf ( & ret , " req[%u] %p : %s \n " ,
i + + , req , ldb_req_location ( req ) ) ;
2010-11-02 02:40:52 +03:00
req = req - > handle - > parent ;
}
return ret ;
}
/*
return the next module in the chain
*/
struct ldb_module * ldb_module_next ( struct ldb_module * module )
{
return module - > next ;
}
/*
set the next module in the module chain
*/
void ldb_module_set_next ( struct ldb_module * module , struct ldb_module * next )
{
module - > next = next ;
}
/*
get the popt_options pointer in the ldb structure . This allows a ldb
module to change the command line parsing
*/
struct poptOption * * ldb_module_popt_options ( struct ldb_context * ldb )
{
return & ldb - > popt_options ;
}
/*
return the current ldb flags LDB_FLG_ *
*/
uint32_t ldb_module_flags ( struct ldb_context * ldb )
{
return ldb - > flags ;
}