Hi,
(Maybe I should have posted this to OpenLDAP-Devel, but I'm not an
OpenLDAP developer, and I feel a little bit lazy to subscribe to another
one mailing list ;)
The first patch fixes ITS#3971. It needs to be reviewed; I only ran
"make check" (successfully) after applying this patch, but maybe similar
corrections need to be done in tool section of backglue.
The nature of ITS#3971 is the following; we implicitly make
op->o_req_dn->bv_val equal to gi->gi_n[i]->gn_be->be_suffix[0]->bv_val
(backglue.c:338), and op->o_req_dn->bv_val after that can be freed by
rwm (rwm.c:82), thus filling gi->gi_n[i]->gn_be->be_suffix[0]->bv_val
with garbage and rendering backglue inoperational for further
invocations. Replacing assignment by ber_dupbv fixes this.
In comments to ITS#3971, it is stated that backglue works only with
global rwm. In fact, backglue doesn't work with global rwm at all; see
my previous message
(http://www.openldap.org/lists/openldap-software/200510/msg00019.html).
That hang is caused by double (chained) invocation of rwm_op_search on a
single op instance; rwm callback (which is a singleton) is being
inserted to a callback chain twice (rwm.c:729), thus turning it into a
cycle, and making cleanup code (result.c:462) enter an infinite loop. My
second patch offers a kind of workaround for this: iterate over callback
chain, and if rwm callback instance is already there, do nothing.
Even with this patch backglue and global rwm do not work together in
subordinate relays configuration. That's because glue makes no chance
for a global rwm instance to act on subordinates, after relaying is
done. The nature of this misbehaviour seems to be a little bit deeper,
so I didn't investigate this.
Regards,
Dimitri
### PATCH 1 ############################################################
--- backglue.c~ 2005-10-10 20:38:33.000000000 +0400
+++ backglue.c 2005-10-12 04:34:47.000000000 +0400
@@ -335,8 +335,8 @@
dn_match(pdn, &ndn))
{
op->ors_scope = LDAP_SCOPE_BASE;
- op->o_req_dn = op->o_bd->be_suffix[0];
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ ber_dupbv(&op->o_req_dn,
op->o_bd->be_suffix);
+ ber_dupbv(&op->o_req_ndn,
op->o_bd->be_nsuffix);
rs->sr_err = op->o_bd->be_search(op,
rs);
} else if (scope0 == LDAP_SCOPE_SUBTREE &&
@@ -347,8 +347,8 @@
} else if (scope0 == LDAP_SCOPE_SUBTREE &&
dnIsSuffix(&op->o_bd->be_nsuffix[0],
&ndn))
{
- op->o_req_dn = op->o_bd->be_suffix[0];
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ ber_dupbv(&op->o_req_dn,
op->o_bd->be_suffix);
+ ber_dupbv(&op->o_req_ndn,
op->o_bd->be_nsuffix);
rs->sr_err = op->o_bd->be_search( op,
rs );
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT )
{
gs.err = LDAP_SUCCESS;
########################################################################
### PATCH 2 ############################################################
--- rwm.c~ 2005-10-10 20:38:33.000000000 +0400
+++ rwm.c 2005-10-11 04:30:33.000000000 +0400
@@ -727,15 +727,27 @@
}
cb = rwm_callback_get( op );
+
+ int rwm_callback_found = 0;
+ slap_callback *sc_next;
+
+ for (sc_next = op->o_callback; sc_next; sc_next =
sc_next->sc_next) {
+ if (sc_next == cb) {
+ rwm_callback_found = 1;
+ break;
+ }
+ }
+
+ if (!rwm_callback_found) {
+ cb->sc_response = rwm_swap_attrs;
+ cb->sc_cleanup = NULL;
+ cb->sc_private = (void *)op->ors_attrs;
+ cb->sc_next = op->o_callback;
- cb->sc_response = rwm_swap_attrs;
- cb->sc_cleanup = NULL;
- cb->sc_private = (void *)op->ors_attrs;
- cb->sc_next = op->o_callback;
-
- op->o_callback = cb;
- op->ors_attrs = an;
-
+ op->o_callback = cb;
+ op->ors_attrs = an;
+ }
+
return SLAP_CB_CONTINUE;
error_return:;
########################################################################