]> 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 858cbeb37efbf863a6338e49787e8a5e170bfed7..9b978d9c4e35f49b3690ff2d34bfa5c045ed93fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT 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,20 +182,37 @@ getAllPluginFuncs(
        int             numPB = 0;
        int             rc = LDAP_SUCCESS;
 
-       assert( be );
        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 )  {
@@ -207,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 ) {
@@ -214,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 ) {
@@ -236,7 +283,7 @@ done:
 
        return rc;
 }
-              
+
 /*********************************************************************
  * Function Name:      createExtendedOp
  *
@@ -553,7 +600,9 @@ loadPlugin(
        return rc;
 }
 
-
+/*
+ * Special support for computed attribute plugins
+ */
 int 
 doPluginFNs(
        Backend         *be,    
@@ -561,18 +610,21 @@ 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++ ) {
                /*
-                * FIXME: operation stops at first non-success
-                *
                 * 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
@@ -580,12 +632,16 @@ doPluginFNs(
                 */
                rc = (*pGetPlugin)(pPB);
 
-               if ( rc != LDAP_SUCCESS ) {
+               /*
+                * Only non-postoperation plugins abort processing on
+                * failure (confirmed with SLAPI specification).
+                */
+               if ( !SLAPI_PLUGIN_IS_POST_FN( funcType ) && rc != 0 ) {
                        break;
                }
        }
 
-       ch_free( tmpPlugin );
+       slapi_ch_free( (void **)&tmpPlugin );
 
        return rc;
 }
@@ -617,6 +673,8 @@ netscape_plugin(
                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] );
@@ -632,7 +690,8 @@ netscape_plugin(
 
        if ( iType == SLAPI_PLUGIN_PREOPERATION ||
                        iType == SLAPI_PLUGIN_EXTENDEDOP ||
-                       iType == SLAPI_PLUGIN_POSTOPERATION ) {
+                       iType == SLAPI_PLUGIN_POSTOPERATION ||
+                       iType == SLAPI_PLUGIN_OBJECT ) {
                int rc;
                Slapi_PBlock *pPlugin;
 
@@ -674,6 +733,15 @@ slapi_init(void)
                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;
+       }
+
        return 0;
 }