2003-11-30 02:03:43 +08:00
|
|
|
/* $OpenLDAP$ */
|
2003-11-27 00:05:06 +08:00
|
|
|
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
|
|
*
|
2005-01-02 04:49:32 +08:00
|
|
|
* Copyright 2002-2005 The OpenLDAP Foundation.
|
2003-11-27 00:05:06 +08:00
|
|
|
* Portions Copyright 1997,2002-2003 IBM Corporation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
2003-11-20 13:11:37 +08:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted only as authorized by the OpenLDAP
|
2003-11-27 00:05:06 +08:00
|
|
|
* 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>.
|
|
|
|
*/
|
|
|
|
/* 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
|
2002-12-08 01:19:29 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
#include <ldap_pvt_thread.h>
|
|
|
|
#include <slap.h>
|
|
|
|
#include <slapi.h>
|
2005-03-02 05:16:44 +08:00
|
|
|
#include <lutil.h>
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Note: if ltdl.h is not available, slapi should not be compiled
|
|
|
|
*/
|
|
|
|
#include <ltdl.h>
|
|
|
|
|
2003-12-28 12:14:19 +08:00
|
|
|
static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int,
|
2002-12-08 01:19:29 +08:00
|
|
|
SLAPI_FUNC *, lt_dlhandle * );
|
|
|
|
|
|
|
|
/* pointer to link list of extended objects */
|
|
|
|
static ExtendedOp *pGExtendedOps = NULL;
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: plugin_pblock_new
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: This routine creates a new Slapi_PBlock structure,
|
|
|
|
* loads in the plugin module and executes the init
|
|
|
|
* function provided by the module.
|
|
|
|
*
|
|
|
|
* Input: type - type of the plugin, such as SASL, database, etc.
|
|
|
|
* path - the loadpath to load the module in
|
|
|
|
* initfunc - name of the plugin function to execute first
|
|
|
|
* argc - number of arguements
|
|
|
|
* argv[] - an array of char pointers point to
|
|
|
|
* the arguments passed in via
|
|
|
|
* the configuration file.
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
*
|
|
|
|
* Return Values: a pointer to a newly created Slapi_PBlock structrue or
|
|
|
|
* NULL - function failed
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
|
2003-12-28 12:14:19 +08:00
|
|
|
static Slapi_PBlock *
|
|
|
|
plugin_pblock_new(
|
2002-12-08 01:19:29 +08:00
|
|
|
int type,
|
|
|
|
int argc,
|
|
|
|
char *argv[] )
|
|
|
|
{
|
|
|
|
Slapi_PBlock *pPlugin = NULL;
|
2003-09-27 13:03:16 +08:00
|
|
|
Slapi_PluginDesc *pPluginDesc = NULL;
|
2002-12-08 01:19:29 +08:00
|
|
|
lt_dlhandle hdLoadHandle;
|
|
|
|
int rc;
|
2005-07-25 21:17:15 +08:00
|
|
|
char **av2 = NULL, **ppPluginArgv;
|
|
|
|
char *path = argv[2];
|
|
|
|
char *initfunc = argv[3];
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
pPlugin = slapi_pblock_new();
|
|
|
|
if ( pPlugin == NULL ) {
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2005-07-25 18:53:45 +08:00
|
|
|
slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
|
|
|
|
slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );
|
2002-12-08 01:19:29 +08:00
|
|
|
|
2005-03-02 04:08:36 +08:00
|
|
|
av2 = ldap_charray_dup( argv );
|
2005-07-19 14:47:43 +08:00
|
|
|
if ( av2 == NULL ) {
|
2005-03-02 04:08:36 +08:00
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( argc > 0 ) {
|
|
|
|
ppPluginArgv = &av2[4];
|
|
|
|
} else {
|
|
|
|
ppPluginArgv = NULL;
|
|
|
|
}
|
|
|
|
|
2005-07-25 18:53:45 +08:00
|
|
|
slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );
|
|
|
|
slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );
|
2002-12-08 01:19:29 +08:00
|
|
|
|
2005-07-22 02:07:16 +08:00
|
|
|
rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle );
|
2003-01-22 21:06:46 +08:00
|
|
|
if ( rc != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
2002-12-08 01:19:29 +08:00
|
|
|
|
2003-09-27 13:03:16 +08:00
|
|
|
if ( slapi_pblock_get( pPlugin, SLAPI_PLUGIN_DESCRIPTION, (void **)&pPluginDesc ) == 0 &&
|
|
|
|
pPluginDesc != NULL ) {
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_log_error(SLAPI_LOG_TRACE, "plugin_pblock_new",
|
2003-09-27 13:03:16 +08:00
|
|
|
"Registered plugin %s %s [%s] (%s)\n",
|
|
|
|
pPluginDesc->spd_id,
|
|
|
|
pPluginDesc->spd_version,
|
|
|
|
pPluginDesc->spd_vendor,
|
|
|
|
pPluginDesc->spd_description);
|
|
|
|
}
|
|
|
|
|
2002-12-08 01:19:29 +08:00
|
|
|
done:
|
2003-09-27 13:03:16 +08:00
|
|
|
if ( rc != 0 && pPlugin != NULL ) {
|
2002-12-08 01:19:29 +08:00
|
|
|
slapi_pblock_destroy( pPlugin );
|
|
|
|
pPlugin = NULL;
|
2005-07-19 14:47:43 +08:00
|
|
|
if ( av2 != NULL ) {
|
2005-03-02 04:08:36 +08:00
|
|
|
ldap_charray_free( av2 );
|
|
|
|
}
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return pPlugin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_register_plugin
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: insert the slapi_pblock structure to the end of the plugin
|
|
|
|
* list
|
|
|
|
*
|
|
|
|
* Input: a pointer to a plugin slapi_pblock structure to be added to
|
|
|
|
* the list
|
|
|
|
*
|
|
|
|
* Output: none
|
|
|
|
*
|
|
|
|
* Return Values: LDAP_SUCCESS - successfully inserted.
|
|
|
|
* LDAP_LOCAL_ERROR.
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_register_plugin(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *be,
|
|
|
|
Slapi_PBlock *pPB )
|
|
|
|
{
|
2005-07-25 21:17:15 +08:00
|
|
|
Slapi_PBlock *pTmpPB;
|
|
|
|
Slapi_PBlock *pSavePB;
|
|
|
|
int rc = LDAP_SUCCESS;
|
2002-12-08 01:19:29 +08:00
|
|
|
|
2005-07-22 11:17:36 +08:00
|
|
|
assert( be != NULL );
|
2003-01-21 23:09:58 +08:00
|
|
|
|
2005-07-22 13:26:15 +08:00
|
|
|
pTmpPB = SLAPI_BACKEND_PBLOCK( be );
|
2002-12-08 01:19:29 +08:00
|
|
|
if ( pTmpPB == NULL ) {
|
2005-07-22 13:26:15 +08:00
|
|
|
SLAPI_BACKEND_PBLOCK( be ) = pPB;
|
2002-12-08 01:19:29 +08:00
|
|
|
} else {
|
|
|
|
while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
|
|
|
|
pSavePB = pTmpPB;
|
2005-07-19 14:47:43 +08:00
|
|
|
rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
2005-07-19 14:47:43 +08:00
|
|
|
rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK, (void *)pPB );
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-19 14:47:43 +08:00
|
|
|
return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_get_plugins
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: get the desired type of function pointers defined
|
|
|
|
* in all the plugins
|
|
|
|
*
|
|
|
|
* Input: the type of the functions to get, such as pre-operation,etc.
|
|
|
|
*
|
|
|
|
* Output: none
|
|
|
|
*
|
|
|
|
* Return Values: this routine returns a pointer to an array of function
|
2003-01-27 21:15:21 +08:00
|
|
|
* pointers containing backend-specific plugin functions
|
|
|
|
* followed by global plugin functions
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_get_plugins(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *be,
|
|
|
|
int functype,
|
|
|
|
SLAPI_FUNC **ppFuncPtrs )
|
|
|
|
{
|
|
|
|
|
|
|
|
Slapi_PBlock *pCurrentPB;
|
|
|
|
SLAPI_FUNC FuncPtr;
|
|
|
|
SLAPI_FUNC *pTmpFuncPtr;
|
|
|
|
int numPB = 0;
|
|
|
|
int rc = LDAP_SUCCESS;
|
|
|
|
|
2005-07-18 14:22:33 +08:00
|
|
|
assert( ppFuncPtrs != NULL );
|
2005-07-21 16:34:25 +08:00
|
|
|
|
|
|
|
if ( be == NULL ) {
|
|
|
|
goto done;
|
|
|
|
}
|
2002-12-08 01:19:29 +08:00
|
|
|
|
2005-07-22 13:26:15 +08:00
|
|
|
pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
|
2003-01-27 21:15:21 +08:00
|
|
|
|
2005-07-19 14:47:43 +08:00
|
|
|
while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
|
2002-12-08 01:19:29 +08:00
|
|
|
rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
|
|
if ( FuncPtr != NULL ) {
|
|
|
|
numPB++;
|
|
|
|
}
|
|
|
|
rc = slapi_pblock_get( pCurrentPB,
|
2005-07-19 14:47:43 +08:00
|
|
|
SLAPI_IBM_PBLOCK, &pCurrentPB );
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( numPB == 0 ) {
|
|
|
|
*ppFuncPtrs = NULL;
|
|
|
|
rc = LDAP_SUCCESS;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2003-01-27 21:15:21 +08:00
|
|
|
/*
|
|
|
|
* Now, build the function pointer array of backend-specific
|
|
|
|
* plugins followed by global plugins.
|
|
|
|
*/
|
2002-12-08 01:19:29 +08:00
|
|
|
*ppFuncPtrs = pTmpFuncPtr =
|
|
|
|
(SLAPI_FUNC *)ch_malloc( ( numPB + 1 ) * sizeof(SLAPI_FUNC) );
|
|
|
|
if ( ppFuncPtrs == NULL ) {
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2005-07-22 13:26:15 +08:00
|
|
|
pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
|
2003-01-27 21:15:21 +08:00
|
|
|
|
2002-12-08 01:19:29 +08:00
|
|
|
while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
|
|
|
|
rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
|
|
if ( FuncPtr != NULL ) {
|
|
|
|
*pTmpFuncPtr = FuncPtr;
|
|
|
|
pTmpFuncPtr++;
|
|
|
|
}
|
|
|
|
rc = slapi_pblock_get( pCurrentPB,
|
|
|
|
SLAPI_IBM_PBLOCK, &pCurrentPB );
|
|
|
|
}
|
|
|
|
}
|
2005-07-22 11:17:36 +08:00
|
|
|
|
2005-07-22 11:24:09 +08:00
|
|
|
*pTmpFuncPtr = NULL;
|
|
|
|
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
done:
|
|
|
|
if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
|
|
|
|
ch_free( *ppFuncPtrs );
|
|
|
|
*ppFuncPtrs = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2003-01-27 21:15:21 +08:00
|
|
|
|
2002-12-08 01:19:29 +08:00
|
|
|
/*********************************************************************
|
|
|
|
* Function Name: createExtendedOp
|
|
|
|
*
|
|
|
|
* Description: Creates an extended operation structure and
|
|
|
|
* initializes the fields
|
|
|
|
*
|
|
|
|
* Return value: A newly allocated structure or NULL
|
|
|
|
********************************************************************/
|
|
|
|
ExtendedOp *
|
|
|
|
createExtendedOp()
|
|
|
|
{
|
|
|
|
ExtendedOp *ret;
|
|
|
|
|
2005-07-25 21:17:15 +08:00
|
|
|
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;
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_unregister_extop
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: This routine removes the ExtendedOp structures
|
|
|
|
* asscoiated with a particular extended operation
|
|
|
|
* plugin.
|
|
|
|
*
|
|
|
|
* Input: pBE - pointer to a backend structure
|
|
|
|
* opList - pointer to a linked list of extended
|
|
|
|
* operation structures
|
|
|
|
* pPB - pointer to a slapi parameter block
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
*
|
|
|
|
* Return Value: none
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
void
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_unregister_extop(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *pBE,
|
|
|
|
ExtendedOp **opList,
|
|
|
|
Slapi_PBlock *pPB )
|
|
|
|
{
|
|
|
|
ExtendedOp *pTmpExtOp, *backExtOp;
|
|
|
|
char **pTmpOIDs;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
assert( pBE != NULL); /* unused */
|
|
|
|
#endif /* 0 */
|
|
|
|
assert( opList != NULL );
|
|
|
|
assert( pPB != NULL );
|
|
|
|
|
|
|
|
if ( *opList == NULL ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
slapi_pblock_get( pPB, SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
|
|
|
|
if ( pTmpOIDs == NULL ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
|
|
|
|
backExtOp = NULL;
|
|
|
|
pTmpExtOp = *opList;
|
|
|
|
for ( ; pTmpExtOp != NULL; pTmpExtOp = pTmpExtOp->ext_next) {
|
|
|
|
int rc;
|
|
|
|
rc = strcasecmp( pTmpExtOp->ext_oid.bv_val,
|
|
|
|
pTmpOIDs[ i ] );
|
|
|
|
if ( rc == 0 ) {
|
|
|
|
if ( backExtOp == NULL ) {
|
|
|
|
*opList = pTmpExtOp->ext_next;
|
|
|
|
} else {
|
|
|
|
backExtOp->ext_next
|
|
|
|
= pTmpExtOp->ext_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ch_free( pTmpExtOp );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
backExtOp = pTmpExtOp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_register_extop
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: This routine creates a new ExtendedOp structure, loads
|
|
|
|
* in the extended op module and put the extended op function address
|
|
|
|
* in the structure. The function will not be executed in
|
|
|
|
* this routine.
|
|
|
|
*
|
|
|
|
* Input: pBE - pointer to a backend structure
|
|
|
|
* opList - pointer to a linked list of extended
|
|
|
|
* operation structures
|
|
|
|
* pPB - pointer to a slapi parameter block
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
*
|
|
|
|
* Return Value: an LDAP return code
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_register_extop(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *pBE,
|
|
|
|
ExtendedOp **opList,
|
|
|
|
Slapi_PBlock *pPB )
|
|
|
|
{
|
|
|
|
ExtendedOp *pTmpExtOp = NULL;
|
|
|
|
SLAPI_FUNC tmpFunc;
|
|
|
|
char **pTmpOIDs;
|
|
|
|
int rc = LDAP_OTHER;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ( (*opList) == NULL ) {
|
|
|
|
*opList = createExtendedOp();
|
|
|
|
if ( (*opList) == NULL ) {
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
goto error_return;
|
|
|
|
}
|
|
|
|
pTmpExtOp = *opList;
|
|
|
|
|
|
|
|
} else { /* Find the end of the list */
|
|
|
|
for ( pTmpExtOp = *opList; pTmpExtOp->ext_next != NULL;
|
|
|
|
pTmpExtOp = pTmpExtOp->ext_next )
|
|
|
|
; /* EMPTY */
|
|
|
|
pTmpExtOp->ext_next = createExtendedOp();
|
|
|
|
if ( pTmpExtOp->ext_next == NULL ) {
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
goto error_return;
|
|
|
|
}
|
|
|
|
pTmpExtOp = pTmpExtOp->ext_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = slapi_pblock_get( pPB,SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
|
2003-12-19 18:10:59 +08:00
|
|
|
if ( rc != 0 ) {
|
2002-12-08 01:19:29 +08:00
|
|
|
rc = LDAP_OTHER;
|
|
|
|
goto error_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = slapi_pblock_get(pPB,SLAPI_PLUGIN_EXT_OP_FN, &tmpFunc);
|
|
|
|
if ( rc != 0 ) {
|
|
|
|
rc = LDAP_OTHER;
|
|
|
|
goto error_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (pTmpOIDs == NULL) || (tmpFunc == NULL) ) {
|
|
|
|
rc = LDAP_OTHER;
|
|
|
|
goto error_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
|
|
|
|
pTmpExtOp->ext_oid.bv_val = pTmpOIDs[i];
|
|
|
|
pTmpExtOp->ext_oid.bv_len = strlen( pTmpOIDs[i] );
|
|
|
|
pTmpExtOp->ext_func = tmpFunc;
|
|
|
|
pTmpExtOp->ext_be = pBE;
|
|
|
|
if ( pTmpOIDs[i + 1] != NULL ) {
|
|
|
|
pTmpExtOp->ext_next = createExtendedOp();
|
|
|
|
if ( pTmpExtOp->ext_next == NULL ) {
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pTmpExtOp = pTmpExtOp->ext_next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error_return:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_get_extop_plugin
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: This routine gets the function address for a given function
|
|
|
|
* name.
|
|
|
|
*
|
|
|
|
* Input:
|
|
|
|
* funcName - name of the extended op function, ie. an OID.
|
|
|
|
*
|
|
|
|
* Output: pFuncAddr - the function address of the requested function name.
|
|
|
|
*
|
|
|
|
* Return Values: a pointer to a newly created ExtendOp structrue or
|
|
|
|
* NULL - function failed
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_get_extop_plugin(
|
2002-12-08 01:19:29 +08:00
|
|
|
struct berval *reqoid,
|
|
|
|
SLAPI_FUNC *pFuncAddr )
|
|
|
|
{
|
|
|
|
ExtendedOp *pTmpExtOp;
|
|
|
|
|
|
|
|
assert( reqoid != NULL );
|
|
|
|
assert( pFuncAddr != NULL );
|
|
|
|
|
|
|
|
*pFuncAddr = NULL;
|
|
|
|
|
|
|
|
if ( pGExtendedOps == NULL ) {
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
pTmpExtOp = pGExtendedOps;
|
|
|
|
while ( pTmpExtOp != NULL ) {
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = strcasecmp( reqoid->bv_val, pTmpExtOp->ext_oid.bv_val );
|
|
|
|
if ( rc == 0 ) {
|
|
|
|
*pFuncAddr = pTmpExtOp->ext_func;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pTmpExtOp = pTmpExtOp->ext_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ( *pFuncAddr == NULL ? 1 : 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* This function is similar to slapi_int_get_extop_plugin above. except it returns one OID
|
2002-12-08 01:19:29 +08:00
|
|
|
* 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 *
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_get_supported_extop( int index )
|
2002-12-08 01:19:29 +08:00
|
|
|
{
|
|
|
|
ExtendedOp *ext;
|
|
|
|
|
|
|
|
for ( ext = pGExtendedOps ; ext != NULL && --index >= 0;
|
|
|
|
ext = ext->ext_next) {
|
|
|
|
; /* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ext == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ext->ext_oid ;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
2003-12-28 12:14:19 +08:00
|
|
|
* Function Name: slapi_int_load_plugin
|
2002-12-08 01:19:29 +08:00
|
|
|
*
|
|
|
|
* Description: This routine loads the specified DLL, gets and executes the init function
|
|
|
|
* if requested.
|
|
|
|
*
|
|
|
|
* Input:
|
|
|
|
* pPlugin - a pointer to a Slapi_PBlock struct which will be passed to
|
|
|
|
* the DLL init function.
|
|
|
|
* path - path name of the DLL to be load.
|
|
|
|
* initfunc - either the DLL initialization function or an OID of the
|
|
|
|
* loaded extended operation.
|
|
|
|
* doInit - if it is TRUE, execute the init function, otherwise, save the
|
|
|
|
* function address but not execute it.
|
|
|
|
*
|
|
|
|
* Output: pInitFunc - the function address of the loaded function. This param
|
|
|
|
* should be not be null if doInit is FALSE.
|
|
|
|
* pLdHandle - handle returned by lt_dlopen()
|
|
|
|
*
|
|
|
|
* Return Values: LDAP_SUCCESS, LDAP_LOCAL_ERROR
|
|
|
|
*
|
|
|
|
* Messages: None
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
static int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_load_plugin(
|
2002-12-08 01:19:29 +08:00
|
|
|
Slapi_PBlock *pPlugin,
|
|
|
|
const char *path,
|
|
|
|
const char *initfunc,
|
|
|
|
int doInit,
|
|
|
|
SLAPI_FUNC *pInitFunc,
|
|
|
|
lt_dlhandle *pLdHandle )
|
|
|
|
{
|
|
|
|
int rc = LDAP_SUCCESS;
|
|
|
|
SLAPI_FUNC fpInitFunc = NULL;
|
|
|
|
|
2005-07-18 14:22:33 +08:00
|
|
|
assert( pLdHandle != NULL );
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
if ( lt_dlinit() ) {
|
|
|
|
return LDAP_LOCAL_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* load in the module */
|
|
|
|
*pLdHandle = lt_dlopen( path );
|
|
|
|
if ( *pLdHandle == NULL ) {
|
2005-07-28 16:35:28 +08:00
|
|
|
fprintf( stderr, "failed to load plugin %s: %s\n",
|
|
|
|
path, lt_dlerror() );
|
2002-12-08 01:19:29 +08:00
|
|
|
return LDAP_LOCAL_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
|
|
|
|
if ( fpInitFunc == NULL ) {
|
2005-07-28 16:35:28 +08:00
|
|
|
fprintf( stderr, "failed to find symbol %s in plugin %s: %s\n",
|
|
|
|
initfunc, path, lt_dlerror() );
|
2002-12-08 01:19:29 +08:00
|
|
|
lt_dlclose( *pLdHandle );
|
|
|
|
return LDAP_LOCAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2005-07-22 02:07:16 +08:00
|
|
|
if ( doInit ) {
|
2002-12-08 01:19:29 +08:00
|
|
|
rc = ( *fpInitFunc )( pPlugin );
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
lt_dlclose( *pLdHandle );
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*pInitFunc = fpInitFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2003-01-22 21:06:46 +08:00
|
|
|
/*
|
|
|
|
* Special support for computed attribute plugins
|
|
|
|
*/
|
2002-12-08 01:19:29 +08:00
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_call_plugins(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *be,
|
|
|
|
int funcType,
|
|
|
|
Slapi_PBlock *pPB )
|
|
|
|
{
|
|
|
|
|
2003-01-21 23:09:58 +08:00
|
|
|
int rc = 0;
|
2002-12-08 01:19:29 +08:00
|
|
|
SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL;
|
|
|
|
|
2003-01-24 18:29:24 +08:00
|
|
|
if ( pPB == NULL ) {
|
2003-04-12 20:40:50 +08:00
|
|
|
return 1;
|
2003-01-24 18:29:24 +08:00
|
|
|
}
|
|
|
|
|
2003-12-28 12:14:19 +08:00
|
|
|
rc = slapi_int_get_plugins( be, funcType, &tmpPlugin );
|
2002-12-08 01:19:29 +08:00
|
|
|
if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
|
2003-01-21 22:52:33 +08:00
|
|
|
/* Nothing to do, front-end should ignore. */
|
2003-04-12 20:40:50 +08:00
|
|
|
return 1;
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
|
|
|
|
rc = (*pGetPlugin)(pPB);
|
|
|
|
|
2003-01-21 06:33:50 +08:00
|
|
|
/*
|
|
|
|
* Only non-postoperation plugins abort processing on
|
|
|
|
* failure (confirmed with SLAPI specification).
|
|
|
|
*/
|
|
|
|
if ( !SLAPI_PLUGIN_IS_POST_FN( funcType ) && rc != 0 ) {
|
2003-08-11 17:55:45 +08:00
|
|
|
/*
|
|
|
|
* Plugins generally return negative error codes
|
|
|
|
* to indicate failure, although in the case of
|
|
|
|
* bind plugins they may return SLAPI_BIND_xxx
|
|
|
|
*/
|
2002-12-08 01:19:29 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-01-21 23:09:58 +08:00
|
|
|
slapi_ch_free( (void **)&tmpPlugin );
|
|
|
|
|
2002-12-08 01:19:29 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_read_config(
|
2002-12-08 01:19:29 +08:00
|
|
|
Backend *be,
|
|
|
|
const char *fname,
|
|
|
|
int lineno,
|
|
|
|
int argc,
|
|
|
|
char **argv )
|
|
|
|
{
|
|
|
|
int iType = -1;
|
|
|
|
int numPluginArgc = 0;
|
|
|
|
|
|
|
|
if ( argc < 4 ) {
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: line %d: missing arguments "
|
|
|
|
"in \"plugin <plugin_type> <lib_path> "
|
|
|
|
"<init_function> [<arguments>]\" line\n",
|
|
|
|
fname, lineno );
|
|
|
|
return 1;
|
|
|
|
}
|
2005-07-22 00:35:20 +08:00
|
|
|
|
|
|
|
/* automatically instantiate overlay if necessary */
|
2005-08-01 23:22:56 +08:00
|
|
|
if ( !slapi_over_is_inst( be ) ) {
|
|
|
|
if ( slapi_over_config( be ) != 0 ) {
|
2005-07-22 02:07:16 +08:00
|
|
|
fprintf( stderr, "Failed to instantiate SLAPI overlay\n");
|
2005-07-22 00:35:20 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2002-12-08 01:19:29 +08:00
|
|
|
|
|
|
|
if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {
|
|
|
|
iType = SLAPI_PLUGIN_PREOPERATION;
|
|
|
|
} else if ( strcasecmp( argv[1], "postoperation" ) == 0 ) {
|
|
|
|
iType = SLAPI_PLUGIN_POSTOPERATION;
|
|
|
|
} else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
|
|
|
|
iType = SLAPI_PLUGIN_EXTENDEDOP;
|
2003-01-22 21:06:46 +08:00
|
|
|
} else if ( strcasecmp( argv[1], "object" ) == 0 ) {
|
|
|
|
iType = SLAPI_PLUGIN_OBJECT;
|
2002-12-08 01:19:29 +08:00
|
|
|
} else {
|
|
|
|
fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
|
|
|
|
fname, lineno, argv[1] );
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
numPluginArgc = argc - 4;
|
|
|
|
|
|
|
|
if ( iType == SLAPI_PLUGIN_PREOPERATION ||
|
|
|
|
iType == SLAPI_PLUGIN_EXTENDEDOP ||
|
2003-01-23 17:22:32 +08:00
|
|
|
iType == SLAPI_PLUGIN_POSTOPERATION ||
|
|
|
|
iType == SLAPI_PLUGIN_OBJECT ) {
|
2002-12-08 01:19:29 +08:00
|
|
|
int rc;
|
|
|
|
Slapi_PBlock *pPlugin;
|
|
|
|
|
2005-03-02 04:08:36 +08:00
|
|
|
pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );
|
2002-12-08 01:19:29 +08:00
|
|
|
if (pPlugin == NULL) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
|
2003-12-28 12:14:19 +08:00
|
|
|
rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);
|
2002-12-08 01:19:29 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
slapi_pblock_destroy( pPlugin );
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-28 12:14:19 +08:00
|
|
|
rc = slapi_int_register_plugin( be, pPlugin );
|
2002-12-08 01:19:29 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
|
2003-12-28 12:14:19 +08:00
|
|
|
slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
|
2002-12-08 01:19:29 +08:00
|
|
|
}
|
|
|
|
slapi_pblock_destroy( pPlugin );
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-03-02 04:08:36 +08:00
|
|
|
void
|
|
|
|
slapi_int_plugin_unparse(
|
|
|
|
Backend *be,
|
|
|
|
BerVarray *out
|
|
|
|
)
|
|
|
|
{
|
|
|
|
Slapi_PBlock *pp;
|
2005-07-18 14:22:33 +08:00
|
|
|
int i, j;
|
2005-03-02 04:08:36 +08:00
|
|
|
char **argv, ibuf[32], *ptr;
|
|
|
|
struct berval idx, bv;
|
|
|
|
|
|
|
|
*out = NULL;
|
|
|
|
idx.bv_val = ibuf;
|
|
|
|
i = 0;
|
2005-07-19 14:47:43 +08:00
|
|
|
|
2005-07-22 13:26:15 +08:00
|
|
|
for ( pp = SLAPI_BACKEND_PBLOCK( be );
|
2005-07-19 14:47:43 +08:00
|
|
|
pp != NULL;
|
|
|
|
slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) )
|
|
|
|
{
|
2005-03-02 04:08:36 +08:00
|
|
|
slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv );
|
2005-07-19 14:47:43 +08:00
|
|
|
if ( argv == NULL ) /* could be dynamic plugin */
|
|
|
|
continue;
|
2005-03-02 04:08:36 +08:00
|
|
|
idx.bv_len = sprintf( idx.bv_val, "{%d}", i );
|
|
|
|
bv.bv_len = idx.bv_len;
|
2005-03-02 05:16:44 +08:00
|
|
|
for (j=1; argv[j]; j++) {
|
2005-03-02 04:08:36 +08:00
|
|
|
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 );
|
2005-03-02 05:16:44 +08:00
|
|
|
for (j=1; argv[j]; j++) {
|
2005-03-02 04:08:36 +08:00
|
|
|
if ( j ) *ptr++ = ' ';
|
|
|
|
ptr = lutil_strcopy( ptr, argv[j] );
|
|
|
|
}
|
|
|
|
ber_bvarray_add( out, &bv );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|