Back to index

openldap  2.4.31
Functions | Variables
plugin.c File Reference
#include "portable.h"
#include "ldap_pvt_thread.h"
#include "slap.h"
#include "config.h"
#include "slapi.h"
#include "lutil.h"
#include <ltdl.h>

Go to the source code of this file.

Functions

static int slapi_int_load_plugin (Slapi_PBlock *, const char *, const char *, int, SLAPI_FUNC *, lt_dlhandle *)
static Slapi_PBlock * plugin_pblock_new (int type, int argc, char *argv[])
int slapi_int_register_plugin (Backend *be, Slapi_PBlock *pPB)
int slapi_int_get_plugins (Backend *be, int functype, SLAPI_FUNC **ppFuncPtrs)
ExtendedOp * createExtendedOp ()
void slapi_int_unregister_extop (Backend *pBE, ExtendedOp **opList, Slapi_PBlock *pPB)
int slapi_int_register_extop (Backend *pBE, ExtendedOp **opList, Slapi_PBlock *pPB)
int slapi_int_get_extop_plugin (struct berval *reqoid, SLAPI_FUNC *pFuncAddr)
struct bervalslapi_int_get_supported_extop (int index)
int slapi_int_call_plugins (Backend *be, int funcType, Slapi_PBlock *pPB)
int slapi_int_read_config (Backend *be, const char *fname, int lineno, int argc, char **argv)
void slapi_int_plugin_unparse (Backend *be, BerVarray *out)

Variables

static ExtendedOp * pGExtendedOps = NULL

Function Documentation

ExtendedOp* createExtendedOp ( )

Definition at line 273 of file plugin.c.

{
       ExtendedOp *ret;

       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Slapi_PBlock* plugin_pblock_new ( int  type,
int  argc,
char *  argv[] 
) [static]

Definition at line 65 of file plugin.c.

{
       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 ) {
              rc = LDAP_NO_MEMORY;
              goto done;
       }

       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;
       }

       if ( argc > 0 ) {
              ppPluginArgv = &av2[4];
       } else {
              ppPluginArgv = NULL;
       }

       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;
       }

       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 != 0 && pPlugin != NULL ) {
              slapi_pblock_destroy( pPlugin );
              pPlugin = NULL;
              if ( av2 != NULL ) {
                     ldap_charray_free( av2 );
              }
       }

       return pPlugin;
} 

Here is the call graph for this function:

Here is the caller graph for this function:

int slapi_int_call_plugins ( Backend be,
int  funcType,
Slapi_PBlock *  pPB 
)

Definition at line 586 of file plugin.c.

{

       int rc = 0;
       SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL; 

       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++ ) {
              rc = (*pGetPlugin)(pPB);

              /*
               * Only non-postoperation plugins abort processing on
               * 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;
              }
       }

       slapi_ch_free( (void **)&tmpPlugin );

       return rc;
}

Here is the call graph for this function:

int slapi_int_get_extop_plugin ( struct berval reqoid,
SLAPI_FUNC *  pFuncAddr 
)

Definition at line 459 of file plugin.c.

{
       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 );
}

Here is the call graph for this function:

int slapi_int_get_plugins ( Backend be,
int  functype,
SLAPI_FUNC **  ppFuncPtrs 
)

Definition at line 190 of file plugin.c.

{
 
       Slapi_PBlock  *pCurrentPB; 
       SLAPI_FUNC    FuncPtr;
       SLAPI_FUNC    *pTmpFuncPtr;
       int           numPB = 0;
       int           rc = LDAP_SUCCESS;

       assert( ppFuncPtrs != NULL );

       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 ) {
                     if ( FuncPtr != NULL )  {
                            numPB++;
                     }
                     rc = slapi_pblock_get( pCurrentPB,
                            SLAPI_IBM_PBLOCK, &pCurrentPB );
              }
       }

       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 ) {
              rc = LDAP_NO_MEMORY;
              goto done;
       }

       pCurrentPB = SLAPI_BACKEND_PBLOCK( be );

       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 );
              }
       }

       *pTmpFuncPtr = NULL;


done:
       if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
              ch_free( *ppFuncPtrs );
              *ppFuncPtrs = NULL;
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct berval* slapi_int_get_supported_extop ( int  index) [read]

Definition at line 495 of file plugin.c.

{
        ExtendedOp   *ext;

        for ( ext = pGExtendedOps ; ext != NULL && --index >= 0;
                     ext = ext->ext_next) {
                ; /* empty */
        }

        if ( ext == NULL ) {
              return NULL;
       }

        return &ext->ext_oid ;
}

Here is the caller graph for this function:

static int slapi_int_load_plugin ( Slapi_PBlock *  pPlugin,
const char *  path,
const char *  initfunc,
int  doInit,
SLAPI_FUNC *  pInitFunc,
lt_dlhandle *  pLdHandle 
) [static]

Definition at line 536 of file plugin.c.

{
       int           rc = LDAP_SUCCESS;
       SLAPI_FUNC    fpInitFunc = NULL;

       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 ) {
              rc = ( *fpInitFunc )( pPlugin );
              if ( rc != LDAP_SUCCESS ) {
                     lt_dlclose( *pLdHandle );
              }

       } else {
              *pInitFunc = fpInitFunc;
       }

       return rc;
}

Here is the caller graph for this function:

Definition at line 707 of file plugin.c.

{
       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 );
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slapi_int_read_config ( Backend be,
const char *  fname,
int  lineno,
int  argc,
char **  argv 
)

Definition at line 628 of file plugin.c.

{
       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;
       }

       /* automatically instantiate overlay if necessary */
       if ( !slapi_over_is_inst( be ) ) {
              ConfigReply cr = { 0 };
              if ( slapi_over_config( be, &cr ) != 0 ) {
                     fprintf( stderr, "Failed to instantiate SLAPI overlay: "
                            "err=%d msg=\"%s\"\n", cr.err, cr.msg );
                     return -1;
              }
       }
       
       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;
       } 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] );
              return 1;
       }
       
       numPluginArgc = argc - 4;

       if ( iType == SLAPI_PLUGIN_PREOPERATION ||
                     iType == SLAPI_PLUGIN_EXTENDEDOP ||
                     iType == SLAPI_PLUGIN_POSTOPERATION ||
                     iType == SLAPI_PLUGIN_OBJECT ) {
              int rc;
              Slapi_PBlock *pPlugin;

              pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );
              if (pPlugin == NULL) {
                     return 1;
              }

              if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
                     rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);
                     if ( rc != LDAP_SUCCESS ) {
                            slapi_pblock_destroy( pPlugin );
                            return 1;
                     }
              }

              rc = slapi_int_register_plugin( be, pPlugin );
              if ( rc != LDAP_SUCCESS ) {
                     if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
                            slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
                     }
                     slapi_pblock_destroy( pPlugin );
                     return 1;
              }
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slapi_int_register_extop ( Backend pBE,
ExtendedOp **  opList,
Slapi_PBlock *  pPB 
)

Definition at line 375 of file plugin.c.

{
       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 );
       if ( rc != 0 ) {
              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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slapi_int_register_plugin ( Backend be,
Slapi_PBlock *  pPB 
)

Definition at line 146 of file plugin.c.

{ 
       Slapi_PBlock  *pTmpPB;
       Slapi_PBlock  *pSavePB;
       int            rc = LDAP_SUCCESS;

       assert( be != NULL );

       pTmpPB = SLAPI_BACKEND_PBLOCK( be );
       if ( pTmpPB == NULL ) {
              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 = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK, (void *)pPB ); 
              }
       }
     
       return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void slapi_int_unregister_extop ( Backend pBE,
ExtendedOp **  opList,
Slapi_PBlock *  pPB 
)

Definition at line 307 of file plugin.c.

{
       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;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

ExtendedOp* pGExtendedOps = NULL [static]

Definition at line 39 of file plugin.c.