diff --git a/CHANGES b/CHANGES index ea8469dcbcb6e7af0a6af83d3a387a9f5f271d9e..7e5a9e2d2bf49227c2f3f0c37a0946fb0d2dd979 100644 --- a/CHANGES +++ b/CHANGES @@ -90,6 +90,7 @@ OpenLDAP 2.4.24 Engineering Fixed slapo-refint with subtree rename (ITS#6730) Fixed slapo-rwm double free (ITS#6720) Fixed slapo-rwm crasher (ITS#6632) + Fixed slapo-rwm entry handling (ITS#6760) Fixed slapo-sssvlv initialization (ITS#6649) Fixed slapo-sssvlv to not advertise when unused (ITS#6647) Fixed slapo-sssvlv fix result code (ITS#6685) diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index e792ab3255734c74de2b5284e61b9f48565b169b..c7e277b4aabd8107784e98229c05e52541259c6e 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -916,9 +916,16 @@ rwm_entry_get_rw( Operation *op, struct berval *ndn, /* duplicate & release */ op2.o_bd->bd_info = (BackendInfo *)on; rc = rwm_send_entry( &op2, &rs ); + RS_ASSERT( rs.sr_flags & REP_ENTRY_MUSTFLUSH ); if ( rc == SLAP_CB_CONTINUE ) { *ep = rs.sr_entry; rc = LDAP_SUCCESS; + } else { + assert( rc != LDAP_SUCCESS && rs.sr_entry == *ep ); + *ep = NULL; + op2.o_bd->bd_info = (BackendInfo *)on->on_info; + be_entry_release_r( &op2, rs.sr_entry ); + op2.o_bd->bd_info = (BackendInfo *)on; } } @@ -1461,6 +1468,7 @@ cleanup_attr:; return 0; } +/* Should return SLAP_CB_CONTINUE or failure, never LDAP_SUCCESS. */ static int rwm_send_entry( Operation *op, SlapReply *rs ) { @@ -1469,7 +1477,6 @@ rwm_send_entry( Operation *op, SlapReply *rs ) (struct ldaprwmap *)on->on_bi.bi_private; Entry *e = NULL; - slap_mask_t flags; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; dncookie dc; @@ -1486,7 +1493,6 @@ rwm_send_entry( Operation *op, SlapReply *rs ) dc.ctx = "searchEntryDN"; e = rs->sr_entry; - flags = rs->sr_flags; if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { /* FIXME: all we need to duplicate are: * - dn @@ -1494,15 +1500,17 @@ rwm_send_entry( Operation *op, SlapReply *rs ) * - attributes that are requested * - no values if attrsonly is set */ - e = entry_dup( e ); if ( e == NULL ) { rc = LDAP_NO_MEMORY; goto fail; } - - flags &= ~REP_ENTRY_MUSTRELEASE; - flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED ); + } else if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { + /* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible + * with REP_ENTRY_MODIFIABLE */ + RS_ASSERT( 0 ); + rc = 1; + goto fail; } /* @@ -1534,22 +1542,21 @@ rwm_send_entry( Operation *op, SlapReply *rs ) * to return, and remap them accordingly */ (void)rwm_attrs( op, rs, &e->e_attrs, 1 ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - /* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible - * with REP_ENTRY_MODIFIABLE */ - if ( rs->sr_entry == e ) { - rc = 1; - goto fail; + if ( e != rs->sr_entry ) { + /* Reimplementing rs_replace_entry(), I suppose to + * bypass our own dubious rwm_entry_release_rw() */ + if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { + rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; + op->o_bd->bd_info = (BackendInfo *)on->on_info; + be_entry_release_r( op, rs->sr_entry ); + op->o_bd->bd_info = (BackendInfo *)on; + } else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { + entry_free( rs->sr_entry ); } - - op->o_bd->bd_info = (BackendInfo *)on->on_info; - be_entry_release_r( op, rs->sr_entry ); - op->o_bd->bd_info = (BackendInfo *)on; + rs->sr_entry = e; + rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED; } - rs->sr_entry = e; - rs->sr_flags = flags; - return SLAP_CB_CONTINUE; fail:;