Issue 6785 - slapo-chain mishandles sr_text/sr_matched
Summary: slapo-chain mishandles sr_text/sr_matched
Status: UNCONFIRMED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: overlays (show other issues)
Version: unspecified
Hardware: All All
: Low normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-12 11:52 UTC by Hallvard Furuseth
Modified: 2021-08-05 15:49 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Hallvard Furuseth 2011-01-12 11:52:09 UTC
Full_Name: Hallvard B Furuseth
Version: HEAD
OS: 
URL: 
Submission from: (NULL) (193.157.198.89)
Submitted by: hallvard


ldap_chain_response() can send sr_text/sr_matched which refers to a
different error than sr_err and rc.

It saves rs-> sr_err, sr_text, sr_matched to three local variables and
can restore them later, but not maintain the text and matched variables
in parallel with err.  Also it does not track/reset/obey
REP_MATCHED_MUSTBEFREED along with sr_matched.

Fails test032-chain with the asserts below.  However there may be
non-success result with the wrong text/matched too, that cannot be
assert()ed.

Come to think of it, maybe the last issues applies to ITS#6774 too?
REP_MATCHED_MUSTBEFREED, mismatch between failure code and text/matched.

Index: servers/slapd/back-ldap/chain.c
@@ -1019,4 +1019,14 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 	rs->sr_ref = NULL;
 
+	const char *bad_incoming_matched = NULL, *bad_incoming_text = NULL;
+	switch ( sr_err ) {
+	case LDAP_SUCCESS:
+	case LDAP_COMPARE_TRUE:
+	case LDAP_COMPARE_FALSE:
+		bad_incoming_matched = matched;
+	case LDAP_REFERRAL:
+		bad_incoming_text = text;
+	}
+
 	/* we need this to know if back-ldap returned any result */
 	lb.lb_lc = lc;
@@ -1169,4 +1179,15 @@ cannot_chain:;
 
 dont_chain:;
+	switch ( sr_err ) {
+	case LDAP_SUCCESS:
+	case LDAP_COMPARE_TRUE:
+	case LDAP_COMPARE_FALSE:
+		assert( !matched || bad_incoming_matched );
+	case LDAP_REFERRAL:
+		assert( !text || bad_incoming_text );
+	}
+	assert( rc != LDAP_SUCCESS ||
+			(( !text    || bad_incoming_text) &&
+			 ( !matched || bad_incoming_matched )));
 	rs->sr_err = sr_err;
 	rs->sr_type = sr_type;
Comment 1 ando@openldap.org 2011-01-18 22:31:46 UTC
> Full_Name: Hallvard B Furuseth
> Version: HEAD
> OS:
> URL:
> Submission from: (NULL) (193.157.198.89)
> Submitted by: hallvard
>
>
> ldap_chain_response() can send sr_text/sr_matched which refers to a
> different error than sr_err and rc.
>
> It saves rs-> sr_err, sr_text, sr_matched to three local variables and
> can restore them later, but not maintain the text and matched variables
> in parallel with err.  Also it does not track/reset/obey
> REP_MATCHED_MUSTBEFREED along with sr_matched.
>
> Fails test032-chain with the asserts below.  However there may be
> non-success result with the wrong text/matched too, that cannot be
> assert()ed.
>
> Come to think of it, maybe the last issues applies to ITS#6774 too?
> REP_MATCHED_MUSTBEFREED, mismatch between failure code and text/matched.
>
> Index: servers/slapd/back-ldap/chain.c
> @@ -1019,4 +1019,14 @@ ldap_chain_response( Operation *op, SlapReply *rs )
>  	rs->sr_ref = NULL;
>
> +	const char *bad_incoming_matched = NULL, *bad_incoming_text = NULL;
> +	switch ( sr_err ) {
> +	case LDAP_SUCCESS:
> +	case LDAP_COMPARE_TRUE:
> +	case LDAP_COMPARE_FALSE:
> +		bad_incoming_matched = matched;
> +	case LDAP_REFERRAL:
> +		bad_incoming_text = text;
> +	}
> +
>  	/* we need this to know if back-ldap returned any result */
>  	lb.lb_lc = lc;
> @@ -1169,4 +1179,15 @@ cannot_chain:;
>
>  dont_chain:;
> +	switch ( sr_err ) {
> +	case LDAP_SUCCESS:
> +	case LDAP_COMPARE_TRUE:
> +	case LDAP_COMPARE_FALSE:
> +		assert( !matched || bad_incoming_matched );
> +	case LDAP_REFERRAL:
> +		assert( !text || bad_incoming_text );
> +	}
> +	assert( rc != LDAP_SUCCESS ||
> +			(( !text    || bad_incoming_text) &&
> +			 ( !matched || bad_incoming_matched )));
>  	rs->sr_err = sr_err;
>  	rs->sr_type = sr_type;

What do you suggest?  To use a local SlapReply instead of hijacking the
one passed as argument?

p.

Comment 2 Hallvard Furuseth 2011-01-19 08:25:43 UTC
masarati@aero.polimi.it writes:
> What do you suggest?  To use a local SlapReply instead of hijacking the
> one passed as argument?

Not my call, I haven't looked enough at the code to know what it's doing.

-- 
Hallvard

Comment 3 Quanah Gibson-Mount 2017-04-07 23:52:01 UTC
moved from Incoming to Software Bugs
Comment 4 Quanah Gibson-Mount 2021-06-24 15:47:48 UTC
Probably fixed by

commit 0c8afb036a8137ba07d6a6f9172022b34aa88633
Author: Ondřej Kuzník <ondra@mistotebe.net>
Date:   Tue Mar 9 17:31:01 2021 +0000

    ITS#9444 Manage sr_ref/sr_matched flags accordingly

    send_ldap_response() clears them immediately even if we never attached
    the data to be freed, so when we reinstate them, the flags are gone and
    the next send_ldap_response() doesn't consider freeing them.
Comment 5 Quanah Gibson-Mount 2021-08-05 15:49:08 UTC
Not fully fixed, needs additional work