-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2007 The OpenLDAP Foundation.
+ * Portions Copyright 1997,2002-2003 IBM Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
*/
-/*
- * (C) Copyright IBM Corp. 1997,2002
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is
- * given to IBM Corporation. This software is provided ``as is''
- * without express or implied warranty.
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by IBM Corporation for use in
+ * IBM products and subsequently ported to OpenLDAP Software by
+ * Steve Omrani. Additional significant contributors include:
+ * Luke Howard
*/
#include "portable.h"
-#include "slapi_common.h"
#include <ldap_pvt_thread.h>
#include <slap.h>
#include <slapi.h>
+#include <lutil.h>
/*
* Note: if ltdl.h is not available, slapi should not be compiled
*/
#include <ltdl.h>
-static int loadPlugin( Slapi_PBlock *, const char *, const char *, int,
+static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int,
SLAPI_FUNC *, lt_dlhandle * );
/* pointer to link list of extended objects */
static ExtendedOp *pGExtendedOps = NULL;
/*********************************************************************
- * Function Name: newPlugin
+ * Function Name: plugin_pblock_new
*
* Description: This routine creates a new Slapi_PBlock structure,
* loads in the plugin module and executes the init
* Messages: None
*********************************************************************/
-Slapi_PBlock *
-newPlugin(
+static Slapi_PBlock *
+plugin_pblock_new(
int type,
- const char *path,
- const char *initfunc,
int argc,
char *argv[] )
{
Slapi_PBlock *pPlugin = NULL;
+ Slapi_PluginDesc *pPluginDesc = NULL;
lt_dlhandle hdLoadHandle;
int rc;
+ char **av2 = NULL, **ppPluginArgv;
+ char *path = argv[2];
+ char *initfunc = argv[3];
pPlugin = slapi_pblock_new();
if ( pPlugin == NULL ) {
goto done;
}
- rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)type );
- if ( rc != LDAP_SUCCESS ) {
+ slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
+ slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );
+
+ av2 = ldap_charray_dup( argv );
+ if ( av2 == NULL ) {
+ rc = LDAP_NO_MEMORY;
goto done;
}
- rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)argc );
- if ( rc != LDAP_SUCCESS ) {
- goto done;
+ if ( argc > 0 ) {
+ ppPluginArgv = &av2[4];
+ } else {
+ ppPluginArgv = NULL;
}
- rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)argv );
- if ( rc != LDAP_SUCCESS ) {
+ slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );
+ slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );
+
+ rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle );
+ if ( rc != 0 ) {
goto done;
}
- rc = loadPlugin( pPlugin, path, initfunc, TRUE, NULL, &hdLoadHandle );
+ if ( slapi_pblock_get( pPlugin, SLAPI_PLUGIN_DESCRIPTION, (void **)&pPluginDesc ) == 0 &&
+ pPluginDesc != NULL ) {
+ slapi_log_error(SLAPI_LOG_TRACE, "plugin_pblock_new",
+ "Registered plugin %s %s [%s] (%s)\n",
+ pPluginDesc->spd_id,
+ pPluginDesc->spd_version,
+ pPluginDesc->spd_vendor,
+ pPluginDesc->spd_description);
+ }
done:
- if ( rc != LDAP_SUCCESS && pPlugin != NULL ) {
+ if ( rc != 0 && pPlugin != NULL ) {
slapi_pblock_destroy( pPlugin );
pPlugin = NULL;
+ if ( av2 != NULL ) {
+ ldap_charray_free( av2 );
+ }
}
return pPlugin;
}
/*********************************************************************
- * Function Name: insertPlugin
+ * Function Name: slapi_int_register_plugin
*
* Description: insert the slapi_pblock structure to the end of the plugin
* list
* Messages: None
*********************************************************************/
int
-insertPlugin(
+slapi_int_register_plugin(
Backend *be,
Slapi_PBlock *pPB )
{
- Slapi_PBlock *pTmpPB;
- Slapi_PBlock *pSavePB;
- int rc = LDAP_SUCCESS;
+ Slapi_PBlock *pTmpPB;
+ Slapi_PBlock *pSavePB;
+ int rc = LDAP_SUCCESS;
- pTmpPB = (Slapi_PBlock *)(be->be_pb);
-
+ assert( be != NULL );
+
+ pTmpPB = SLAPI_BACKEND_PBLOCK( be );
if ( pTmpPB == NULL ) {
- be->be_pb = (void *)pPB;
+ SLAPI_BACKEND_PBLOCK( be ) = pPB;
} else {
while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
pSavePB = pTmpPB;
- rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK,
- &pTmpPB );
- if ( rc != LDAP_SUCCESS ) {
- rc = LDAP_OTHER;
- }
+ rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
}
if ( rc == LDAP_SUCCESS ) {
- rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK,
- (void *)pPB );
- if ( rc != LDAP_SUCCESS ) {
- rc = LDAP_OTHER;
- }
+ rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK, (void *)pPB );
}
}
- return rc;
+ return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
}
/*********************************************************************
- * Function Name: getAllPluginFuncs
+ * Function Name: slapi_int_get_plugins
*
* Description: get the desired type of function pointers defined
* in all the plugins
* Output: none
*
* Return Values: this routine returns a pointer to an array of function
- * pointers
+ * pointers containing backend-specific plugin functions
+ * followed by global plugin functions
*
* Messages: None
*********************************************************************/
int
-getAllPluginFuncs(
+slapi_int_get_plugins(
Backend *be,
int functype,
SLAPI_FUNC **ppFuncPtrs )
int numPB = 0;
int rc = LDAP_SUCCESS;
- assert( be );
- assert( ppFuncPtrs );
+ assert( ppFuncPtrs != NULL );
- pCurrentPB = (Slapi_PBlock *)(be->be_pb);
-
- if ( pCurrentPB == NULL ) {
- /*
- * LDAP_OTHER is returned if no plugins are installed
- */
- rc = LDAP_OTHER;
+ if ( be == NULL ) {
goto done;
}
+ pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
+
while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
if ( rc == LDAP_SUCCESS ) {
numPB++;
}
rc = slapi_pblock_get( pCurrentPB,
- SLAPI_IBM_PBLOCK, &pCurrentPB );
+ SLAPI_IBM_PBLOCK, &pCurrentPB );
}
}
- if ( rc != LDAP_SUCCESS ) {
- goto done;
- }
-
if ( numPB == 0 ) {
*ppFuncPtrs = NULL;
rc = LDAP_SUCCESS;
goto done;
}
+ /*
+ * Now, build the function pointer array of backend-specific
+ * plugins followed by global plugins.
+ */
*ppFuncPtrs = pTmpFuncPtr =
(SLAPI_FUNC *)ch_malloc( ( numPB + 1 ) * sizeof(SLAPI_FUNC) );
if ( ppFuncPtrs == NULL ) {
goto done;
}
- pCurrentPB = (Slapi_PBlock *)(be->be_pb);
+ pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
+
while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
if ( rc == LDAP_SUCCESS ) {
SLAPI_IBM_PBLOCK, &pCurrentPB );
}
}
- *pTmpFuncPtr = NULL ;
+
+ *pTmpFuncPtr = NULL;
+
done:
if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
return rc;
}
-
+
/*********************************************************************
* Function Name: createExtendedOp
*
{
ExtendedOp *ret;
- ret = (ExtendedOp *)ch_malloc(sizeof(ExtendedOp));
- if ( ret != NULL ) {
- ret->ext_oid.bv_val = NULL;
- ret->ext_oid.bv_len = 0;
- ret->ext_func = NULL;
- ret->ext_be = NULL;
- ret->ext_next = NULL;
- }
+ ret = (ExtendedOp *)slapi_ch_malloc(sizeof(ExtendedOp));
+ ret->ext_oid.bv_val = NULL;
+ ret->ext_oid.bv_len = 0;
+ ret->ext_func = NULL;
+ ret->ext_be = NULL;
+ ret->ext_next = NULL;
return ret;
}
/*********************************************************************
- * Function Name: removeExtendedOp
+ * Function Name: slapi_int_unregister_extop
*
* Description: This routine removes the ExtendedOp structures
* asscoiated with a particular extended operation
* Messages: None
*********************************************************************/
void
-removeExtendedOp(
+slapi_int_unregister_extop(
Backend *pBE,
ExtendedOp **opList,
Slapi_PBlock *pPB )
/*********************************************************************
- * Function Name: newExtendedOp
+ * Function Name: slapi_int_register_extop
*
* Description: This routine creates a new ExtendedOp structure, loads
* in the extended op module and put the extended op function address
* Messages: None
*********************************************************************/
int
-newExtendedOp(
+slapi_int_register_extop(
Backend *pBE,
ExtendedOp **opList,
Slapi_PBlock *pPB )
}
rc = slapi_pblock_get( pPB,SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
- if ( rc != LDAP_SUCCESS ) {
+ if ( rc != 0 ) {
rc = LDAP_OTHER;
goto error_return;
}
}
/*********************************************************************
- * Function Name: getPluginFunc
+ * Function Name: slapi_int_get_extop_plugin
*
* Description: This routine gets the function address for a given function
* name.
* Messages: None
*********************************************************************/
int
-getPluginFunc(
+slapi_int_get_extop_plugin(
struct berval *reqoid,
SLAPI_FUNC *pFuncAddr )
{
}
/***************************************************************************
- * This function is similar to getPluginFunc above. except it returns one OID
+ * This function is similar to slapi_int_get_extop_plugin above. except it returns one OID
* per call. It is called from root_dse_info (root_dse.c).
* The function is a modified version of get_supported_extop (file extended.c).
***************************************************************************/
struct berval *
-ns_get_supported_extop( int index )
+slapi_int_get_supported_extop( int index )
{
ExtendedOp *ext;
}
/*********************************************************************
- * Function Name: loadPlugin
+ * Function Name: slapi_int_load_plugin
*
* Description: This routine loads the specified DLL, gets and executes the init function
* if requested.
*********************************************************************/
static int
-loadPlugin(
+slapi_int_load_plugin(
Slapi_PBlock *pPlugin,
const char *path,
const char *initfunc,
int rc = LDAP_SUCCESS;
SLAPI_FUNC fpInitFunc = NULL;
- assert( pLdHandle );
+ assert( pLdHandle != NULL );
if ( lt_dlinit() ) {
return LDAP_LOCAL_ERROR;
/* load in the module */
*pLdHandle = lt_dlopen( path );
if ( *pLdHandle == NULL ) {
+ fprintf( stderr, "failed to load plugin %s: %s\n",
+ path, lt_dlerror() );
return LDAP_LOCAL_ERROR;
}
fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
if ( fpInitFunc == NULL ) {
+ fprintf( stderr, "failed to find symbol %s in plugin %s: %s\n",
+ initfunc, path, lt_dlerror() );
lt_dlclose( *pLdHandle );
return LDAP_LOCAL_ERROR;
}
- if ( doInit == TRUE ) {
+ if ( doInit ) {
rc = ( *fpInitFunc )( pPlugin );
if ( rc != LDAP_SUCCESS ) {
lt_dlclose( *pLdHandle );
return rc;
}
-
+/*
+ * Special support for computed attribute plugins
+ */
int
-doPluginFNs(
+slapi_int_call_plugins(
Backend *be,
int funcType,
Slapi_PBlock *pPB )
{
- int rc = LDAP_SUCCESS;
+ int rc = 0;
SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL;
- rc = getAllPluginFuncs(be, funcType, &tmpPlugin );
+ if ( pPB == NULL ) {
+ return 1;
+ }
+
+ rc = slapi_int_get_plugins( be, funcType, &tmpPlugin );
if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
+ /* Nothing to do, front-end should ignore. */
return rc;
}
for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
- /*
- * FIXME: we should provide here a sort of sandbox,
- * to protect from plugin faults; e.g. trap signals
- * and longjump here, marking the plugin as unsafe for
- * later executions ...
- */
rc = (*pGetPlugin)(pPB);
/*
* failure (confirmed with SLAPI specification).
*/
if ( !SLAPI_PLUGIN_IS_POST_FN( funcType ) && rc != 0 ) {
+ /*
+ * Plugins generally return negative error codes
+ * to indicate failure, although in the case of
+ * bind plugins they may return SLAPI_BIND_xxx
+ */
break;
}
}
- ch_free( tmpPlugin );
+ slapi_ch_free( (void **)&tmpPlugin );
return rc;
}
int
-netscape_plugin(
+slapi_int_read_config(
Backend *be,
const char *fname,
int lineno,
{
int iType = -1;
int numPluginArgc = 0;
- char **ppPluginArgv = NULL;
if ( argc < 4 ) {
fprintf( stderr,
fname, lineno );
return 1;
}
+
+ /* automatically instantiate overlay if necessary */
+ if ( !slapi_over_is_inst( be ) ) {
+ if ( slapi_over_config( be ) != 0 ) {
+ fprintf( stderr, "Failed to instantiate SLAPI overlay\n");
+ return -1;
+ }
+ }
if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {
iType = SLAPI_PLUGIN_PREOPERATION;
iType = SLAPI_PLUGIN_POSTOPERATION;
} else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
iType = SLAPI_PLUGIN_EXTENDEDOP;
- } else if ( strcasecmp( argv[1], "opattrsp" ) == 0 ) {
- iType = SLAPI_PLUGIN_OPATTR_SP;
+ } else if ( strcasecmp( argv[1], "object" ) == 0 ) {
+ iType = SLAPI_PLUGIN_OBJECT;
} else {
fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
fname, lineno, argv[1] );
}
numPluginArgc = argc - 4;
- if ( numPluginArgc > 0 ) {
- ppPluginArgv = &argv[4];
- } else {
- ppPluginArgv = NULL;
- }
if ( iType == SLAPI_PLUGIN_PREOPERATION ||
iType == SLAPI_PLUGIN_EXTENDEDOP ||
iType == SLAPI_PLUGIN_POSTOPERATION ||
- iType == SLAPI_PLUGIN_OPATTR_SP ) {
+ iType == SLAPI_PLUGIN_OBJECT ) {
int rc;
Slapi_PBlock *pPlugin;
- pPlugin = newPlugin( iType, argv[2], argv[3],
- numPluginArgc, ppPluginArgv );
+ pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );
if (pPlugin == NULL) {
return 1;
}
if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
- rc = newExtendedOp(be, &pGExtendedOps, pPlugin);
+ rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);
if ( rc != LDAP_SUCCESS ) {
slapi_pblock_destroy( pPlugin );
return 1;
}
}
- rc = insertPlugin( be, pPlugin );
+ rc = slapi_int_register_plugin( be, pPlugin );
if ( rc != LDAP_SUCCESS ) {
if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
- removeExtendedOp( be, &pGExtendedOps, pPlugin );
+ slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
}
slapi_pblock_destroy( pPlugin );
return 1;
return 0;
}
-int
-slapi_init(void)
+void
+slapi_int_plugin_unparse(
+ Backend *be,
+ BerVarray *out
+)
{
- if ( ldap_pvt_thread_mutex_init( &slapi_hn_mutex ) ) {
- return -1;
- }
-
- if ( ldap_pvt_thread_mutex_init( &slapi_time_mutex ) ) {
- return -1;
- }
-
- if ( ldap_pvt_thread_mutex_init( &slapi_printmessage_mutex ) ) {
- return -1;
- }
-
- slapi_log_file = ch_strdup( LDAP_RUNDIR LDAP_DIRSEP "errors" );
- if ( slapi_log_file == NULL ) {
- return -1;
+ Slapi_PBlock *pp;
+ int i, j;
+ char **argv, ibuf[32], *ptr;
+ struct berval idx, bv;
+
+ *out = NULL;
+ idx.bv_val = ibuf;
+ i = 0;
+
+ for ( pp = SLAPI_BACKEND_PBLOCK( be );
+ pp != NULL;
+ slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) )
+ {
+ slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv );
+ if ( argv == NULL ) /* could be dynamic plugin */
+ continue;
+ idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i );
+ if ( idx.bv_len >= sizeof( ibuf ) ) {
+ /* FIXME: just truncating by now */
+ idx.bv_len = sizeof( ibuf ) - 1;
+ }
+ bv.bv_len = idx.bv_len;
+ for (j=1; argv[j]; j++) {
+ bv.bv_len += strlen(argv[j]);
+ if ( j ) bv.bv_len++;
+ }
+ bv.bv_val = ch_malloc( bv.bv_len + 1 );
+ ptr = lutil_strcopy( bv.bv_val, ibuf );
+ for (j=1; argv[j]; j++) {
+ if ( j ) *ptr++ = ' ';
+ ptr = lutil_strcopy( ptr, argv[j] );
+ }
+ ber_bvarray_add( out, &bv );
}
-
- return 0;
}