]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-monitor/init.c
fix zeroing out attribute values (should fix ITS#5311)
[openldap] / servers / slapd / back-monitor / init.c
index f2b798b1561f272ac54dcf7e8d9a0bb45b8c2602..1f82cfa9a411442d9ff3a961f397f33f8240b6e1 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2001-2007 The OpenLDAP Foundation.
+ * Copyright 2001-2008 The OpenLDAP Foundation.
  * Portions Copyright 2001-2003 Pierangelo Masarati.
  * All rights reserved.
  *
@@ -291,7 +291,7 @@ typedef struct entry_limbo_t {
        slap_overinst           *el_on;
        Entry                   *el_e;
        Attribute               *el_a;
-       struct berval           el_ndn;
+       struct berval           *el_ndn;
        struct berval           el_nbase;
        int                     el_scope;
        struct berval           el_filter;
@@ -337,7 +337,8 @@ monitor_back_register_backend_limbo(
 
 int
 monitor_back_register_database_limbo(
-       BackendDB               *be )
+       BackendDB               *be,
+       struct berval   *ndn )
 {
        entry_limbo_t   **elpp, el = { 0 };
        monitor_info_t  *mi;
@@ -356,8 +357,9 @@ monitor_back_register_database_limbo(
        el.el_type = LIMBO_DATABASE;
 
        el.el_be = be;
+       el.el_ndn = ndn;
        
-       for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+       for ( elpp = &mi->mi_entry_limbo;
                        *elpp;
                        elpp = &(*elpp)->el_next )
                /* go to last */;
@@ -529,7 +531,7 @@ done:;
                el.el_mss = mss;
                el.el_flags = flags;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                                *elpp;
                                elpp = &(*elpp)->el_next )
                        /* go to last */;
@@ -743,7 +745,7 @@ done:;
                el.el_mss = mss;
                el.el_flags = flags;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                                *elpp;
                                elpp = &(*elpp)->el_next )
                        /* go to last */;
@@ -813,9 +815,9 @@ monitor_search2ndn(
                return -1;
        }
 
-       op = (Operation *) &opbuf;
        thrctx = ldap_pvt_thread_pool_context();
-       connection_fake_init( &conn, op, thrctx );
+       connection_fake_init( &conn, &opbuf, thrctx );
+       op = &opbuf.ob_op;
 
        op->o_tag = LDAP_REQ_SEARCH;
 
@@ -1062,9 +1064,7 @@ done:;
                entry_limbo_t   **elpp, el = { 0 };
 
                el.el_type = LIMBO_ATTRS;
-               if ( !BER_BVISNULL( &ndn ) ) {
-                       ber_dupbv( &el.el_ndn, &ndn );
-               }
+               el.el_ndn = ndn_in;
                if ( !BER_BVISNULL( nbase ) ) {
                        ber_dupbv( &el.el_nbase, nbase);
                }
@@ -1076,7 +1076,7 @@ done:;
                el.el_a = attrs_dup( a );
                el.el_cb = cb;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                                *elpp;
                                elpp = &(*elpp)->el_next )
                        /* go to last */;
@@ -1102,9 +1102,6 @@ done:;
                        if ( !BER_BVISNULL( &el.el_nbase ) ) {
                                ch_free( &el.el_nbase.bv_val );
                        }
-                       if ( !BER_BVISNULL( &el.el_ndn ) ) {
-                               ch_free( el.el_ndn.bv_val );
-                       }
                        return -1;
                }
        }
@@ -1189,7 +1186,7 @@ monitor_back_unregister_entry(
        } else {
                entry_limbo_t   **elpp;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                        *elpp;
                        elpp = &(*elpp)->el_next )
                {
@@ -1203,6 +1200,9 @@ monitor_back_unregister_entry(
                                for ( cb = elp->el_cb; cb; cb = next ) {
                                        /* FIXME: call callbacks? */
                                        next = cb->mc_next;
+                                       if ( cb->mc_dispose ) {
+                                               cb->mc_dispose( &cb->mc_private );
+                                       }
                                        ch_free( cb );
                                }
                                assert( elp->el_e != NULL );
@@ -1320,7 +1320,7 @@ monitor_back_unregister_entry_parent(
        } else {
                entry_limbo_t   **elpp;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                        *elpp;
                        elpp = &(*elpp)->el_next )
                {
@@ -1337,6 +1337,9 @@ monitor_back_unregister_entry_parent(
                                for ( cb = elp->el_cb; cb; cb = next ) {
                                        /* FIXME: call callbacks? */
                                        next = cb->mc_next;
+                                       if ( cb->mc_dispose ) {
+                                               cb->mc_dispose( &cb->mc_private );
+                                       }
                                        ch_free( cb );
                                }
                                assert( elp->el_e != NULL );
@@ -1496,14 +1499,12 @@ monitor_back_unregister_entry_attrs(
                        ber_memfree( ndn.bv_val );
                }
 
-               if ( e ) {
-                       monitor_cache_release( mi, e );
-               }
+               monitor_cache_release( mi, e );
 
        } else {
                entry_limbo_t   **elpp;
 
-               for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+               for ( elpp = &mi->mi_entry_limbo;
                        *elpp;
                        elpp = &(*elpp)->el_next )
                {
@@ -1519,6 +1520,9 @@ monitor_back_unregister_entry_attrs(
                                for ( cb = elp->el_cb; cb; cb = next ) {
                                        /* FIXME: call callbacks? */
                                        next = cb->mc_next;
+                                       if ( cb->mc_dispose ) {
+                                               cb->mc_dispose( &cb->mc_private );
+                                       }
                                        ch_free( cb );
                                }
                                assert( elp->el_e == NULL );
@@ -2029,7 +2033,6 @@ monitor_back_initialize(
        bi->bi_tool_entry_reindex = 0;
        bi->bi_tool_sync = 0;
        bi->bi_tool_dn2id_get = 0;
-       bi->bi_tool_id2entry_get = 0;
        bi->bi_tool_entry_modify = 0;
 
        bi->bi_connection_init = 0;
@@ -2052,7 +2055,8 @@ monitor_back_initialize(
 
 int
 monitor_back_db_init(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *c)
 {
        int                     rc;
        struct berval           dn = BER_BVC( SLAPD_MONITOR_DN ),
@@ -2063,23 +2067,24 @@ monitor_back_db_init(
        monitor_subsys_t        *ms;
 
        /*
-        * register subsys
+        * database monitor can be defined once only
         */
-       for ( ms = known_monitor_subsys; ms->mss_name != NULL; ms++ ) {
-               if ( monitor_back_register_subsys( ms ) ) {
-                       return -1;
+       if ( be_monitor != NULL ) {
+               if (c) {
+                       snprintf(c->msg, sizeof(c->msg),"only one monitor database allowed");
                }
+               return( -1 );
        }
+       be_monitor = be;
 
        /*
-        * database monitor can be defined once only
+        * register subsys
         */
-       if ( be_monitor != NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "only one monitor database is allowed\n", 0, 0, 0 );
-               return( -1 );
+       for ( ms = known_monitor_subsys; ms->mss_name != NULL; ms++ ) {
+               if ( monitor_back_register_subsys( ms ) ) {
+                       return -1;
+               }
        }
-       be_monitor = be;
 
        /* indicate system schema supported */
        SLAP_BFLAGS(be) |= SLAP_BFLAG_MONITOR;
@@ -2101,7 +2106,7 @@ monitor_back_db_init(
 
        be->be_private = &monitor_info;
 
-       be2 = select_backend( &ndn, 0, 0 );
+       be2 = select_backend( &ndn, 0 );
        if ( be2 != be ) {
                char    *type = be2->bd_info->bi_type;
 
@@ -2110,19 +2115,57 @@ monitor_back_db_init(
                        type = oi->oi_orig->bi_type;
                }
 
-               Debug( LDAP_DEBUG_ANY,
-                       "\"monitor\" database serving namingContext \"%s\" "
-                       "is hidden by \"%s\" database serving namingContext \"%s\".\n",
-                       pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
+               if (c) {
+                       snprintf(c->msg, sizeof(c->msg),
+                                       "\"monitor\" database serving namingContext \"%s\" "
+                                       "is hidden by \"%s\" database serving namingContext \"%s\".\n",
+                                       pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
+               }
                return -1;
        }
 
        return 0;
 }
 
+static void
+monitor_back_destroy_limbo_entry(
+       entry_limbo_t   *el,
+       int             dispose )
+{
+       if ( el->el_e ) {
+               entry_free( el->el_e );
+       }
+       if ( el->el_a ) {
+               attrs_free( el->el_a );
+       }
+       if ( !BER_BVISNULL( &el->el_nbase ) ) {
+               ber_memfree( el->el_nbase.bv_val );
+       }
+       if ( !BER_BVISNULL( &el->el_filter ) ) {
+               ber_memfree( el->el_filter.bv_val );
+       }
+
+       /* NOTE: callbacks are not copied; so only free them
+        * if disposing of */
+       if ( el->el_cb && dispose != 0 ) {
+               monitor_callback_t *next;
+
+               for ( ; el->el_cb; el->el_cb = next ) {
+                       next = el->el_cb->mc_next;
+                       if ( el->el_cb->mc_dispose ) {
+                               el->el_cb->mc_dispose( &el->el_cb->mc_private );
+                       }
+                       ch_free( el->el_cb );
+               }
+       }
+
+       ch_free( el );
+}
+
 int
 monitor_back_db_open(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr)
 {
        monitor_info_t          *mi = (monitor_info_t *)be->be_private;
        struct monitor_subsys_t **ms;
@@ -2142,6 +2185,8 @@ monitor_back_db_open(
                " attributes, which must be explicitly requested."),
                BER_BVNULL };
 
+       int                     retcode = 0;
+
        assert( be_monitor != NULL );
        if ( be != be_monitor ) {
                be_monitor = be;
@@ -2321,7 +2366,7 @@ monitor_back_db_open(
        monitor_subsys_opened = 1;
 
        if ( mi->mi_entry_limbo ) {
-               entry_limbo_t   *el = (entry_limbo_t *)mi->mi_entry_limbo;
+               entry_limbo_t   *el = mi->mi_entry_limbo;
 
                for ( ; el; ) {
                        entry_limbo_t   *tmp;
@@ -2350,7 +2395,7 @@ monitor_back_db_open(
 
                        case LIMBO_ATTRS:
                                rc = monitor_back_register_entry_attrs(
-                                               &el->el_ndn,
+                                               el->el_ndn,
                                                el->el_a,
                                                el->el_cb,
                                                &el->el_nbase,
@@ -2360,7 +2405,7 @@ monitor_back_db_open(
 
                        case LIMBO_CB:
                                rc = monitor_back_register_entry_callback(
-                                               &el->el_ndn,
+                                               el->el_ndn,
                                                el->el_cb,
                                                &el->el_nbase,
                                                el->el_scope,
@@ -2372,7 +2417,7 @@ monitor_back_db_open(
                                break;
 
                        case LIMBO_DATABASE:
-                               rc = monitor_back_register_database( el->el_be );
+                               rc = monitor_back_register_database( el->el_be, el->el_ndn );
                                break;
 
                        case LIMBO_OVERLAY_INFO:
@@ -2387,37 +2432,20 @@ monitor_back_db_open(
                                assert( 0 );
                        }
 
-                       if ( el->el_e ) {
-                               entry_free( el->el_e );
-                       }
-                       if ( el->el_a ) {
-                               attrs_free( el->el_a );
-                       }
-                       if ( !BER_BVISNULL( &el->el_ndn ) ) {
-                               ber_memfree( el->el_ndn.bv_val );
-                       }
-                       if ( !BER_BVISNULL( &el->el_nbase ) ) {
-                               ber_memfree( el->el_nbase.bv_val );
-                       }
-                       if ( !BER_BVISNULL( &el->el_filter ) ) {
-                               ber_memfree( el->el_filter.bv_val );
-                       }
-                       if ( el->el_cb && rc != 0 ) {
-                               if ( el->el_cb->mc_dispose ) {
-                                       el->el_cb->mc_dispose( &el->el_cb->mc_private );
-                               }
-                               ch_free( el->el_cb );
-                       }
-
                        tmp = el;
                        el = el->el_next;
-                       ch_free( tmp );
+                       monitor_back_destroy_limbo_entry( tmp, rc );
+
+                       if ( rc != 0 ) {
+                               /* try all, but report error at end */
+                               retcode = 1;
+                       }
                }
 
                mi->mi_entry_limbo = NULL;
        }
 
-       return( 0 );
+       return retcode;
 }
 
 int
@@ -2454,7 +2482,8 @@ monitor_back_db_config(
 
 int
 monitor_back_db_destroy(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr)
 {
        monitor_info_t  *mi = ( monitor_info_t * )be->be_private;
 
@@ -2484,6 +2513,16 @@ monitor_back_db_destroy(
 
                ch_free( monitor_subsys );
        }
+
+       if ( mi->mi_entry_limbo ) {
+               entry_limbo_t   *el = mi->mi_entry_limbo;
+
+               for ( ; el; ) {
+                       entry_limbo_t *tmp = el;
+                       el = el->el_next;
+                       monitor_back_destroy_limbo_entry( tmp, 1 );
+               }
+       }
        
        ldap_pvt_thread_mutex_destroy( &monitor_info.mi_cache_mutex );