From 3e9b558af99f4033885be773548a0850992971c6 Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount <quanah@openldap.org> Date: Wed, 14 Apr 2010 19:28:47 +0000 Subject: [PATCH] ITS#5340 fixes --- CHANGES | 1 + servers/slapd/proto-slap.h | 4 ++++ servers/slapd/result.c | 44 ++++++++++++++++++++++++++++++++++++++ servers/slapd/slap.h | 1 + 4 files changed, 50 insertions(+) diff --git a/CHANGES b/CHANGES index a3a3aceda2..49f3d52149 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ OpenLDAP 2.4.21 Release (2009/12/20) Fixed liblutil for negative microsecond offsets (ITS#6405) Fixed slapd global settings to work without restart (ITS#6428) Fixed slapd looping with SSL/TLS connections (ITS#6412) + Fixed slapd REP_ENTRY flag handling (ITS#5340) Fixed slapd syncrepl freeing tasks from queue (ITS#6413) Fixed slapd syncrepl parsing of tls defaults (ITS#6419) Fixed slapd syncrepl uninitialized variables (ITS#6425) diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index b3d7767ee9..8bf3580084 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1512,6 +1512,10 @@ LDAP_SLAPD_F (int) get_alias_dn LDAP_P(( /* * result.c */ +LDAP_SLAPD_F (void) rs_replace_entry LDAP_P(( Operation *op, + SlapReply *rs, slap_overinst *on, Entry *e )); +LDAP_SLAPD_F (int) rs_ensure_entry_modifiable LDAP_P(( Operation *op, + SlapReply *rs, slap_overinst *on )); LDAP_SLAPD_F (void) slap_send_ldap_result LDAP_P(( Operation *op, SlapReply *rs )); LDAP_SLAPD_F (void) send_ldap_sasl LDAP_P(( Operation *op, SlapReply *rs )); LDAP_SLAPD_F (void) send_ldap_disconnect LDAP_P(( Operation *op, SlapReply *rs )); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index e74f7dbf35..38152e0194 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -132,6 +132,50 @@ slap_req2res( ber_tag_t tag ) return tag; } +#ifdef RS_ASSERT +#elif 0 && defined LDAP_DEVEL /* FIXME: this should not crash. ITS#5340. */ +#define RS_ASSERT assert +#else +#define RS_ASSERT(cond) ((void) 0) +#endif + +/* Set rs->sr_entry after obyeing and clearing sr_flags & REP_ENTRY_MASK. */ +void +rs_replace_entry( Operation *op, SlapReply *rs, slap_overinst *on, Entry *e ) +{ + slap_mask_t e_flags = rs->sr_flags & REP_ENTRY_MUSTFLUSH; + + if ( e_flags && rs->sr_entry != NULL ) { + RS_ASSERT( e_flags != REP_ENTRY_MUSTFLUSH ); + if ( !(e_flags & REP_ENTRY_MUSTRELEASE) ) { + entry_free( rs->sr_entry ); + } else if ( on != NULL ) { + overlay_entry_release_ov( op, rs->sr_entry, 0, on ); + } else { + be_entry_release_rw( op, rs->sr_entry, 0 ); + } + } + rs->sr_flags &= ~REP_ENTRY_MASK; + rs->sr_entry = e; +} + +/* + * Ensure rs->sr_entry is modifiable, by duplicating it if necessary. + * Obey sr_flags. Set REP_ENTRY_<MODIFIABLE, and MUSTBEFREED if duplicated>. + * Return nonzero if rs->sr_entry was replaced. + */ +int +rs_ensure_entry_modifiable( Operation *op, SlapReply *rs, slap_overinst *on ) +{ + if ( rs->sr_flags & REP_ENTRY_MODIFIABLE ) { + RS_ASSERT((rs->sr_flags & REP_ENTRY_MUSTFLUSH)==REP_ENTRY_MUSTBEFREED); + return 0; + } + rs_replace_entry( op, rs, on, entry_dup( rs->sr_entry )); + rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED; + return 1; +} + static long send_ldap_ber( Operation *op, BerElement *ber ) diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 2eb949d8c6..56e1768170 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2090,6 +2090,7 @@ struct SlapReply { #define REP_ENTRY_MUSTBEFREED 0x0002U #define REP_ENTRY_MUSTRELEASE 0x0004U #define REP_ENTRY_MASK (REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED|REP_ENTRY_MUSTRELEASE) +#define REP_ENTRY_MUSTFLUSH (REP_ENTRY_MUSTBEFREED|REP_ENTRY_MUSTRELEASE) #define REP_MATCHED_MUSTBEFREED 0x0010U #define REP_MATCHED_MASK (REP_MATCHED_MUSTBEFREED) -- GitLab