Back to index

openldap  2.4.31
plugin.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2002-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1997,2002-2003 IBM Corporation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by IBM Corporation for use in
00018  * IBM products and subsequently ported to OpenLDAP Software by
00019  * Steve Omrani.  Additional significant contributors include:
00020  *    Luke Howard
00021  */
00022 
00023 #include "portable.h"
00024 #include "ldap_pvt_thread.h"
00025 #include "slap.h"
00026 #include "config.h"
00027 #include "slapi.h"
00028 #include "lutil.h"
00029 
00030 /*
00031  * Note: if ltdl.h is not available, slapi should not be compiled
00032  */
00033 #include <ltdl.h>
00034 
00035 static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int, 
00036        SLAPI_FUNC *, lt_dlhandle * );
00037 
00038 /* pointer to link list of extended objects */
00039 static ExtendedOp *pGExtendedOps = NULL;
00040 
00041 /*********************************************************************
00042  * Function Name:      plugin_pblock_new
00043  *
00044  * Description:        This routine creates a new Slapi_PBlock structure,
00045  *                     loads in the plugin module and executes the init
00046  *                     function provided by the module.
00047  *
00048  * Input:              type - type of the plugin, such as SASL, database, etc.
00049  *                     path - the loadpath to load the module in
00050  *                     initfunc - name of the plugin function to execute first
00051  *                     argc - number of arguements
00052  *                     argv[] - an array of char pointers point to
00053  *                              the arguments passed in via
00054  *                              the configuration file.
00055  *
00056  * Output:             
00057  *
00058  * Return Values:      a pointer to a newly created Slapi_PBlock structrue or
00059  *                     NULL - function failed 
00060  *
00061  * Messages:           None
00062  *********************************************************************/
00063 
00064 static Slapi_PBlock *
00065 plugin_pblock_new(
00066        int type, 
00067        int argc, 
00068        char *argv[] ) 
00069 {
00070        Slapi_PBlock  *pPlugin = NULL; 
00071        Slapi_PluginDesc *pPluginDesc = NULL;
00072        lt_dlhandle   hdLoadHandle;
00073        int           rc;
00074        char          **av2 = NULL, **ppPluginArgv;
00075        char          *path = argv[2];
00076        char          *initfunc = argv[3];
00077 
00078        pPlugin = slapi_pblock_new();
00079        if ( pPlugin == NULL ) {
00080               rc = LDAP_NO_MEMORY;
00081               goto done;
00082        }
00083 
00084        slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
00085        slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );
00086 
00087        av2 = ldap_charray_dup( argv );
00088        if ( av2 == NULL ) {
00089               rc = LDAP_NO_MEMORY;
00090               goto done;
00091        }
00092 
00093        if ( argc > 0 ) {
00094               ppPluginArgv = &av2[4];
00095        } else {
00096               ppPluginArgv = NULL;
00097        }
00098 
00099        slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );
00100        slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );
00101 
00102        rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle );
00103        if ( rc != 0 ) {
00104               goto done;
00105        }
00106 
00107        if ( slapi_pblock_get( pPlugin, SLAPI_PLUGIN_DESCRIPTION, (void **)&pPluginDesc ) == 0 &&
00108             pPluginDesc != NULL ) {
00109               slapi_log_error(SLAPI_LOG_TRACE, "plugin_pblock_new",
00110                             "Registered plugin %s %s [%s] (%s)\n",
00111                             pPluginDesc->spd_id,
00112                             pPluginDesc->spd_version,
00113                             pPluginDesc->spd_vendor,
00114                             pPluginDesc->spd_description);
00115        }
00116 
00117 done:
00118        if ( rc != 0 && pPlugin != NULL ) {
00119               slapi_pblock_destroy( pPlugin );
00120               pPlugin = NULL;
00121               if ( av2 != NULL ) {
00122                      ldap_charray_free( av2 );
00123               }
00124        }
00125 
00126        return pPlugin;
00127 } 
00128 
00129 /*********************************************************************
00130  * Function Name:      slapi_int_register_plugin
00131  *
00132  * Description:        insert the slapi_pblock structure to the end of the plugin
00133  *                     list 
00134  *
00135  * Input:              a pointer to a plugin slapi_pblock structure to be added to 
00136  *                     the list
00137  *
00138  * Output:             none
00139  *
00140  * Return Values:      LDAP_SUCCESS - successfully inserted.
00141  *                     LDAP_LOCAL_ERROR.
00142  *
00143  * Messages:           None
00144  *********************************************************************/
00145 int 
00146 slapi_int_register_plugin(
00147        Backend *be, 
00148        Slapi_PBlock *pPB )
00149 { 
00150        Slapi_PBlock  *pTmpPB;
00151        Slapi_PBlock  *pSavePB;
00152        int            rc = LDAP_SUCCESS;
00153 
00154        assert( be != NULL );
00155 
00156        pTmpPB = SLAPI_BACKEND_PBLOCK( be );
00157        if ( pTmpPB == NULL ) {
00158               SLAPI_BACKEND_PBLOCK( be ) = pPB;
00159        } else {
00160               while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
00161                      pSavePB = pTmpPB;
00162                      rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
00163               }
00164 
00165               if ( rc == LDAP_SUCCESS ) { 
00166                      rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK, (void *)pPB ); 
00167               }
00168        }
00169      
00170        return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
00171 }
00172        
00173 /*********************************************************************
00174  * Function Name:      slapi_int_get_plugins
00175  *
00176  * Description:        get the desired type of function pointers defined 
00177  *                     in all the plugins 
00178  *
00179  * Input:              the type of the functions to get, such as pre-operation,etc.
00180  *
00181  * Output:             none
00182  *
00183  * Return Values:      this routine returns a pointer to an array of function
00184  *                     pointers containing backend-specific plugin functions
00185  *                     followed by global plugin functions
00186  *
00187  * Messages:           None
00188  *********************************************************************/
00189 int 
00190 slapi_int_get_plugins(
00191        Backend *be,         
00192        int functype, 
00193        SLAPI_FUNC **ppFuncPtrs )
00194 {
00195  
00196        Slapi_PBlock  *pCurrentPB; 
00197        SLAPI_FUNC    FuncPtr;
00198        SLAPI_FUNC    *pTmpFuncPtr;
00199        int           numPB = 0;
00200        int           rc = LDAP_SUCCESS;
00201 
00202        assert( ppFuncPtrs != NULL );
00203 
00204        if ( be == NULL ) {
00205               goto done;
00206        }
00207 
00208        pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
00209 
00210        while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
00211               rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
00212               if ( rc == LDAP_SUCCESS ) {
00213                      if ( FuncPtr != NULL )  {
00214                             numPB++;
00215                      }
00216                      rc = slapi_pblock_get( pCurrentPB,
00217                             SLAPI_IBM_PBLOCK, &pCurrentPB );
00218               }
00219        }
00220 
00221        if ( numPB == 0 ) {
00222               *ppFuncPtrs = NULL;
00223               rc = LDAP_SUCCESS;
00224               goto done;
00225        }
00226 
00227        /*
00228         * Now, build the function pointer array of backend-specific
00229         * plugins followed by global plugins.
00230         */
00231        *ppFuncPtrs = pTmpFuncPtr = 
00232               (SLAPI_FUNC *)ch_malloc( ( numPB + 1 ) * sizeof(SLAPI_FUNC) ); 
00233        if ( ppFuncPtrs == NULL ) {
00234               rc = LDAP_NO_MEMORY;
00235               goto done;
00236        }
00237 
00238        pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
00239 
00240        while ( pCurrentPB != NULL && rc == LDAP_SUCCESS )  {
00241               rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
00242               if ( rc == LDAP_SUCCESS ) {
00243                      if ( FuncPtr != NULL )  {
00244                             *pTmpFuncPtr = FuncPtr;
00245                             pTmpFuncPtr++;
00246                      } 
00247                      rc = slapi_pblock_get( pCurrentPB,
00248                                    SLAPI_IBM_PBLOCK, &pCurrentPB );
00249               }
00250        }
00251 
00252        *pTmpFuncPtr = NULL;
00253 
00254 
00255 done:
00256        if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
00257               ch_free( *ppFuncPtrs );
00258               *ppFuncPtrs = NULL;
00259        }
00260 
00261        return rc;
00262 }
00263 
00264 /*********************************************************************
00265  * Function Name:      createExtendedOp
00266  *
00267  * Description: Creates an extended operation structure and
00268  *              initializes the fields
00269  *
00270  * Return value: A newly allocated structure or NULL
00271  ********************************************************************/
00272 ExtendedOp *
00273 createExtendedOp()
00274 {
00275        ExtendedOp *ret;
00276 
00277        ret = (ExtendedOp *)slapi_ch_malloc(sizeof(ExtendedOp));
00278        ret->ext_oid.bv_val = NULL;
00279        ret->ext_oid.bv_len = 0;
00280        ret->ext_func = NULL;
00281        ret->ext_be = NULL;
00282        ret->ext_next = NULL;
00283 
00284        return ret;
00285 }
00286 
00287 
00288 /*********************************************************************
00289  * Function Name:      slapi_int_unregister_extop
00290  *
00291  * Description:        This routine removes the ExtendedOp structures 
00292  *                                    asscoiated with a particular extended operation 
00293  *                                    plugin.
00294  *
00295  * Input:              pBE - pointer to a backend structure
00296  *                     opList - pointer to a linked list of extended
00297  *                              operation structures
00298  *                     pPB - pointer to a slapi parameter block
00299  *
00300  * Output:
00301  *
00302  * Return Value:       none
00303  *
00304  * Messages:           None
00305  *********************************************************************/
00306 void
00307 slapi_int_unregister_extop(
00308        Backend *pBE, 
00309        ExtendedOp **opList, 
00310        Slapi_PBlock *pPB )
00311 {
00312        ExtendedOp    *pTmpExtOp, *backExtOp;
00313        char          **pTmpOIDs;
00314        int           i;
00315 
00316 #if 0
00317        assert( pBE != NULL); /* unused */
00318 #endif /* 0 */
00319        assert( opList != NULL );
00320        assert( pPB != NULL );
00321 
00322        if ( *opList == NULL ) {
00323               return;
00324        }
00325 
00326        slapi_pblock_get( pPB, SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
00327        if ( pTmpOIDs == NULL ) {
00328               return;
00329        }
00330 
00331        for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
00332               backExtOp = NULL;
00333               pTmpExtOp = *opList;
00334               for ( ; pTmpExtOp != NULL; pTmpExtOp = pTmpExtOp->ext_next) {
00335                      int    rc;
00336                      rc = strcasecmp( pTmpExtOp->ext_oid.bv_val,
00337                                    pTmpOIDs[ i ] );
00338                      if ( rc == 0 ) {
00339                             if ( backExtOp == NULL ) {
00340                                    *opList = pTmpExtOp->ext_next;
00341                             } else {
00342                                    backExtOp->ext_next
00343                                           = pTmpExtOp->ext_next;
00344                             }
00345 
00346                             ch_free( pTmpExtOp );
00347                             break;
00348                      }
00349                      backExtOp = pTmpExtOp;
00350               }
00351        }
00352 }
00353 
00354 
00355 /*********************************************************************
00356  * Function Name:      slapi_int_register_extop
00357  *
00358  * Description:        This routine creates a new ExtendedOp structure, loads
00359  *                     in the extended op module and put the extended op function address
00360  *                     in the structure. The function will not be executed in
00361  *                     this routine.
00362  *
00363  * Input:              pBE - pointer to a backend structure
00364  *                     opList - pointer to a linked list of extended
00365  *                              operation structures
00366  *                     pPB - pointer to a slapi parameter block
00367  *
00368  * Output:
00369  *
00370  * Return Value:       an LDAP return code
00371  *
00372  * Messages:           None
00373  *********************************************************************/
00374 int 
00375 slapi_int_register_extop(
00376        Backend *pBE,        
00377        ExtendedOp **opList, 
00378        Slapi_PBlock *pPB )
00379 {
00380        ExtendedOp    *pTmpExtOp = NULL;
00381        SLAPI_FUNC    tmpFunc;
00382        char          **pTmpOIDs;
00383        int           rc = LDAP_OTHER;
00384        int           i;
00385 
00386        if ( (*opList) == NULL ) { 
00387               *opList = createExtendedOp();
00388               if ( (*opList) == NULL ) {
00389                      rc = LDAP_NO_MEMORY;
00390                      goto error_return;
00391               }
00392               pTmpExtOp = *opList;
00393               
00394        } else {                        /* Find the end of the list */
00395               for ( pTmpExtOp = *opList; pTmpExtOp->ext_next != NULL;
00396                             pTmpExtOp = pTmpExtOp->ext_next )
00397                      ; /* EMPTY */
00398               pTmpExtOp->ext_next = createExtendedOp();
00399               if ( pTmpExtOp->ext_next == NULL ) {
00400                      rc = LDAP_NO_MEMORY;
00401                      goto error_return;
00402               }
00403               pTmpExtOp = pTmpExtOp->ext_next;
00404        }
00405 
00406        rc = slapi_pblock_get( pPB,SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
00407        if ( rc != 0 ) {
00408               rc = LDAP_OTHER;
00409               goto error_return;
00410        }
00411 
00412        rc = slapi_pblock_get(pPB,SLAPI_PLUGIN_EXT_OP_FN, &tmpFunc);
00413        if ( rc != 0 ) {
00414               rc = LDAP_OTHER;
00415               goto error_return;
00416        }
00417 
00418        if ( (pTmpOIDs == NULL) || (tmpFunc == NULL) ) {
00419               rc = LDAP_OTHER;
00420               goto error_return;
00421        }
00422 
00423        for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
00424               pTmpExtOp->ext_oid.bv_val = pTmpOIDs[i];
00425               pTmpExtOp->ext_oid.bv_len = strlen( pTmpOIDs[i] );
00426               pTmpExtOp->ext_func = tmpFunc;
00427               pTmpExtOp->ext_be = pBE;
00428               if ( pTmpOIDs[i + 1] != NULL ) {
00429                      pTmpExtOp->ext_next = createExtendedOp();
00430                      if ( pTmpExtOp->ext_next == NULL ) {
00431                             rc = LDAP_NO_MEMORY;
00432                             break;
00433                      }
00434                      pTmpExtOp = pTmpExtOp->ext_next;
00435               }
00436        }
00437 
00438 error_return:
00439        return rc;
00440 }
00441 
00442 /*********************************************************************
00443  * Function Name:      slapi_int_get_extop_plugin
00444  *
00445  * Description:        This routine gets the function address for a given function
00446  *                     name.
00447  *
00448  * Input:
00449  *                     funcName - name of the extended op function, ie. an OID.
00450  *
00451  * Output:             pFuncAddr - the function address of the requested function name.
00452  *
00453  * Return Values:      a pointer to a newly created ExtendOp structrue or
00454  *                     NULL - function failed
00455  *
00456  * Messages:           None
00457  *********************************************************************/
00458 int 
00459 slapi_int_get_extop_plugin(
00460        struct berval *reqoid,             
00461        SLAPI_FUNC *pFuncAddr ) 
00462 {
00463        ExtendedOp    *pTmpExtOp;
00464 
00465        assert( reqoid != NULL );
00466        assert( pFuncAddr != NULL );
00467 
00468        *pFuncAddr = NULL;
00469 
00470        if ( pGExtendedOps == NULL ) {
00471               return LDAP_OTHER;
00472        }
00473 
00474        pTmpExtOp = pGExtendedOps;
00475        while ( pTmpExtOp != NULL ) {
00476               int    rc;
00477               
00478               rc = strcasecmp( reqoid->bv_val, pTmpExtOp->ext_oid.bv_val );
00479               if ( rc == 0 ) {
00480                      *pFuncAddr = pTmpExtOp->ext_func;
00481                      break;
00482               }
00483               pTmpExtOp = pTmpExtOp->ext_next;
00484        }
00485 
00486        return ( *pFuncAddr == NULL ? 1 : 0 );
00487 }
00488 
00489 /***************************************************************************
00490  * This function is similar to slapi_int_get_extop_plugin above. except it returns one OID
00491  * per call. It is called from root_dse_info (root_dse.c).
00492  * The function is a modified version of get_supported_extop (file extended.c).
00493  ***************************************************************************/
00494 struct berval *
00495 slapi_int_get_supported_extop( int index )
00496 {
00497         ExtendedOp   *ext;
00498 
00499         for ( ext = pGExtendedOps ; ext != NULL && --index >= 0;
00500                      ext = ext->ext_next) {
00501                 ; /* empty */
00502         }
00503 
00504         if ( ext == NULL ) {
00505               return NULL;
00506        }
00507 
00508         return &ext->ext_oid ;
00509 }
00510 
00511 /*********************************************************************
00512  * Function Name:      slapi_int_load_plugin
00513  *
00514  * Description:        This routine loads the specified DLL, gets and executes the init function
00515  *                     if requested.
00516  *
00517  * Input:
00518  *                     pPlugin - a pointer to a Slapi_PBlock struct which will be passed to
00519  *                               the DLL init function.
00520  *                     path - path name of the DLL to be load.
00521  *                     initfunc - either the DLL initialization function or an OID of the
00522  *                                loaded extended operation.
00523  *                     doInit - if it is TRUE, execute the init function, otherwise, save the
00524  *                              function address but not execute it.
00525  *
00526  * Output:             pInitFunc - the function address of the loaded function. This param
00527  *                                 should be not be null if doInit is FALSE.
00528  *                     pLdHandle - handle returned by lt_dlopen()
00529  *
00530  * Return Values:      LDAP_SUCCESS, LDAP_LOCAL_ERROR
00531  *
00532  * Messages:           None
00533  *********************************************************************/
00534 
00535 static int 
00536 slapi_int_load_plugin(
00537        Slapi_PBlock  *pPlugin,
00538        const char    *path,
00539        const char    *initfunc, 
00540        int           doInit,
00541        SLAPI_FUNC    *pInitFunc,
00542        lt_dlhandle   *pLdHandle ) 
00543 {
00544        int           rc = LDAP_SUCCESS;
00545        SLAPI_FUNC    fpInitFunc = NULL;
00546 
00547        assert( pLdHandle != NULL );
00548 
00549        if ( lt_dlinit() ) {
00550               return LDAP_LOCAL_ERROR;
00551        }
00552 
00553        /* load in the module */
00554        *pLdHandle = lt_dlopen( path );
00555        if ( *pLdHandle == NULL ) {
00556               fprintf( stderr, "failed to load plugin %s: %s\n",
00557                       path, lt_dlerror() );
00558               return LDAP_LOCAL_ERROR;
00559        }
00560 
00561        fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
00562        if ( fpInitFunc == NULL ) {
00563               fprintf( stderr, "failed to find symbol %s in plugin %s: %s\n",
00564                       initfunc, path, lt_dlerror() );
00565               lt_dlclose( *pLdHandle );
00566               return LDAP_LOCAL_ERROR;
00567        }
00568 
00569        if ( doInit ) {
00570               rc = ( *fpInitFunc )( pPlugin );
00571               if ( rc != LDAP_SUCCESS ) {
00572                      lt_dlclose( *pLdHandle );
00573               }
00574 
00575        } else {
00576               *pInitFunc = fpInitFunc;
00577        }
00578 
00579        return rc;
00580 }
00581 
00582 /*
00583  * Special support for computed attribute plugins
00584  */
00585 int 
00586 slapi_int_call_plugins(
00587        Backend              *be,   
00588        int           funcType, 
00589        Slapi_PBlock  *pPB )
00590 {
00591 
00592        int rc = 0;
00593        SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL; 
00594 
00595        if ( pPB == NULL ) {
00596               return 1;
00597        }
00598 
00599        rc = slapi_int_get_plugins( be, funcType, &tmpPlugin );
00600        if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
00601               /* Nothing to do, front-end should ignore. */
00602               return rc;
00603        }
00604 
00605        for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
00606               rc = (*pGetPlugin)(pPB);
00607 
00608               /*
00609                * Only non-postoperation plugins abort processing on
00610                * failure (confirmed with SLAPI specification).
00611                */
00612               if ( !SLAPI_PLUGIN_IS_POST_FN( funcType ) && rc != 0 ) {
00613                      /*
00614                       * Plugins generally return negative error codes
00615                       * to indicate failure, although in the case of
00616                       * bind plugins they may return SLAPI_BIND_xxx
00617                       */
00618                      break;
00619               }
00620        }
00621 
00622        slapi_ch_free( (void **)&tmpPlugin );
00623 
00624        return rc;
00625 }
00626 
00627 int
00628 slapi_int_read_config(
00629        Backend              *be,          
00630        const char    *fname, 
00631        int           lineno, 
00632        int           argc, 
00633        char          **argv )
00634 {
00635        int           iType = -1;
00636        int           numPluginArgc = 0;
00637 
00638        if ( argc < 4 ) {
00639               fprintf( stderr,
00640                      "%s: line %d: missing arguments "
00641                      "in \"plugin <plugin_type> <lib_path> "
00642                      "<init_function> [<arguments>]\" line\n",
00643                      fname, lineno );
00644               return 1;
00645        }
00646 
00647        /* automatically instantiate overlay if necessary */
00648        if ( !slapi_over_is_inst( be ) ) {
00649               ConfigReply cr = { 0 };
00650               if ( slapi_over_config( be, &cr ) != 0 ) {
00651                      fprintf( stderr, "Failed to instantiate SLAPI overlay: "
00652                             "err=%d msg=\"%s\"\n", cr.err, cr.msg );
00653                      return -1;
00654               }
00655        }
00656        
00657        if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {
00658               iType = SLAPI_PLUGIN_PREOPERATION;
00659        } else if ( strcasecmp( argv[1], "postoperation" ) == 0 ) {
00660               iType = SLAPI_PLUGIN_POSTOPERATION;
00661        } else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
00662               iType = SLAPI_PLUGIN_EXTENDEDOP;
00663        } else if ( strcasecmp( argv[1], "object" ) == 0 ) {
00664               iType = SLAPI_PLUGIN_OBJECT;
00665        } else {
00666               fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
00667                             fname, lineno, argv[1] );
00668               return 1;
00669        }
00670        
00671        numPluginArgc = argc - 4;
00672 
00673        if ( iType == SLAPI_PLUGIN_PREOPERATION ||
00674                      iType == SLAPI_PLUGIN_EXTENDEDOP ||
00675                      iType == SLAPI_PLUGIN_POSTOPERATION ||
00676                      iType == SLAPI_PLUGIN_OBJECT ) {
00677               int rc;
00678               Slapi_PBlock *pPlugin;
00679 
00680               pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );
00681               if (pPlugin == NULL) {
00682                      return 1;
00683               }
00684 
00685               if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
00686                      rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);
00687                      if ( rc != LDAP_SUCCESS ) {
00688                             slapi_pblock_destroy( pPlugin );
00689                             return 1;
00690                      }
00691               }
00692 
00693               rc = slapi_int_register_plugin( be, pPlugin );
00694               if ( rc != LDAP_SUCCESS ) {
00695                      if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
00696                             slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
00697                      }
00698                      slapi_pblock_destroy( pPlugin );
00699                      return 1;
00700               }
00701        }
00702 
00703        return 0;
00704 }
00705 
00706 void
00707 slapi_int_plugin_unparse(
00708        Backend *be,
00709        BerVarray *out
00710 )
00711 {
00712        Slapi_PBlock *pp;
00713        int i, j;
00714        char **argv, ibuf[32], *ptr;
00715        struct berval idx, bv;
00716 
00717        *out = NULL;
00718        idx.bv_val = ibuf;
00719        i = 0;
00720 
00721        for ( pp = SLAPI_BACKEND_PBLOCK( be );
00722              pp != NULL;
00723              slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) )
00724        {
00725               slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv );
00726               if ( argv == NULL ) /* could be dynamic plugin */
00727                      continue;
00728               idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i );
00729               if ( idx.bv_len >= sizeof( ibuf ) ) {
00730                      /* FIXME: just truncating by now */
00731                      idx.bv_len = sizeof( ibuf ) - 1;
00732               }
00733               bv.bv_len = idx.bv_len;
00734               for (j=1; argv[j]; j++) {
00735                      bv.bv_len += strlen(argv[j]);
00736                      if ( j ) bv.bv_len++;
00737               }
00738               bv.bv_val = ch_malloc( bv.bv_len + 1 );
00739               ptr = lutil_strcopy( bv.bv_val, ibuf );
00740               for (j=1; argv[j]; j++) {
00741                      if ( j ) *ptr++ = ' ';
00742                      ptr = lutil_strcopy( ptr, argv[j] );
00743               }
00744               ber_bvarray_add( out, &bv );
00745        }
00746 }
00747