]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapi/plugin.c
Do not return pointers into BerElement we do not own
[openldap] / servers / slapd / slapi / plugin.c
index c12e75a5ca101f239d87c33a34612d6499ce2620..9b978d9c4e35f49b3690ff2d34bfa5c045ed93fe 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include "portable.h"
-#include "slapi_common.h"
 #include <ldap_pvt_thread.h>
 #include <slap.h>
 #include <slapi.h>
@@ -26,6 +25,8 @@ static int loadPlugin( Slapi_PBlock *, const char *, const char *, int,
 
 /* pointer to link list of extended objects */
 static ExtendedOp *pGExtendedOps = NULL;
+/* global plugins not associated with a specific backend */
+static Slapi_PBlock *pGPlugins = NULL;
 
 /*********************************************************************
  * Function Name:      newPlugin
@@ -84,6 +85,10 @@ newPlugin(
        }
 
        rc = loadPlugin( pPlugin, path, initfunc, TRUE, NULL, &hdLoadHandle );
+       if ( rc != 0 ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
 
 done:
        if ( rc != LDAP_SUCCESS && pPlugin != NULL ) {
@@ -119,10 +124,13 @@ insertPlugin(
        Slapi_PBlock *pSavePB;
        int    rc = LDAP_SUCCESS;
 
-       pTmpPB = (Slapi_PBlock *)(be->be_pb);
-       
+       pTmpPB = ( be == NULL ) ? pGPlugins : (Slapi_PBlock *)(be->be_pb);
+
        if ( pTmpPB == NULL ) {
-               be->be_pb = (void *)pPB;
+               if ( be != NULL )
+                       be->be_pb = (void *)pPB;
+               else
+                       pGPlugins = pPB;
        } else {
                while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
                        pSavePB = pTmpPB;
@@ -156,7 +164,8 @@ insertPlugin(
  * 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
  *********************************************************************/
@@ -173,27 +182,37 @@ getAllPluginFuncs(
        int             numPB = 0;
        int             rc = LDAP_SUCCESS;
 
-       if ( be == NULL ) {
-               /*
-                * No plugins supported if no backend (yet)
-                */
-               rc = LDAP_OTHER;
-               goto done;
-       }
-
        assert( ppFuncPtrs );
 
-       pCurrentPB = (Slapi_PBlock *)(be->be_pb);
-     
-       if ( pCurrentPB == NULL ) { 
-               /*
-                * LDAP_OTHER is returned if no plugins are installed
-                */
-               rc = LDAP_OTHER;
+       /*
+        * First, count the plugins associated with a specific
+        * backend.
+        */
+       if ( be != NULL ) {
+               pCurrentPB = (Slapi_PBlock *)be->be_pb;
+
+               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 ( rc != LDAP_SUCCESS ) {
                goto done;
        }
 
-       while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
+       /*
+        * Then, count the global plugins.
+        */
+       pCurrentPB = pGPlugins;
+
+       while  ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
                rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
                if ( rc == LDAP_SUCCESS ) {
                        if ( FuncPtr != NULL )  {
@@ -214,6 +233,10 @@ getAllPluginFuncs(
                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 ) {
@@ -221,7 +244,24 @@ getAllPluginFuncs(
                goto done;
        }
 
-       pCurrentPB = (Slapi_PBlock *)(be->be_pb);
+       if ( be != NULL ) {
+               pCurrentPB = (Slapi_PBlock *)be->be_pb;
+
+               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 );
+                       }
+               }
+       }
+
+       pCurrentPB = pGPlugins;
+
        while ( pCurrentPB != NULL && rc == LDAP_SUCCESS )  {
                rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
                if ( rc == LDAP_SUCCESS ) {
@@ -243,7 +283,7 @@ done:
 
        return rc;
 }
-              
+
 /*********************************************************************
  * Function Name:      createExtendedOp
  *
@@ -560,7 +600,9 @@ loadPlugin(
        return rc;
 }
 
-
+/*
+ * Special support for computed attribute plugins
+ */
 int 
 doPluginFNs(
        Backend         *be,    
@@ -568,12 +610,17 @@ doPluginFNs(
        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 0;
+       }
+
+       rc = getAllPluginFuncs( be, funcType, &tmpPlugin );
        if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
-               return rc;
+               /* Nothing to do, front-end should ignore. */
+               return 0;
        }
 
        for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
@@ -594,7 +641,7 @@ doPluginFNs(
                }
        }
 
-       ch_free( tmpPlugin );
+       slapi_ch_free( (void **)&tmpPlugin );
 
        return rc;
 }
@@ -626,8 +673,8 @@ netscape_plugin(
                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] );
@@ -644,7 +691,7 @@ netscape_plugin(
        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;