Subject: ldap_result2error, ldap_parse_result

From: "Howard Chu" <[email-masked]>
Date: Thu, 23 Sep 1999 15:48:10 -0700

I came upon an ambiguous situation regarding the difference between the v2
and v3 LDAP C APIs as implemented in OpenLDAP. I know ldap_result2error is
provided for backward compatibility with v2 clients - that's fine. However,
the implementations that I've seen (looking at OpenLDAP and Mozilla SDK)
have a slight problem that I'd like help resolving.

Here's the Mozilla ldap_result2error, which is a wrapper for
ldap_parse_result:

        lderr_parse = ldap_parse_result( ld, r, &lderr, NULL, NULL, NULL,
            NULL, freeit );

        if ( lderr_parse != LDAP_SUCCESS ) {
                return( lderr_parse );
        }

        return( lderr );

The strategy is "if the parse failed, return the failure code, otherwise
return the server's result code." That makes sense, for the most part.
However, if the parse returns LDAP_MORE_RESULTS_TO_RETURN, then this will be
returned to the caller instead of the server's result code. I believe this
is wrong for a number of reasons:
   The RFC 1823 description of ldap_result2error says that it returns a
result indicating the outcome of the operation. The RFC also explicitly
lists all the possible result codes. The LDAP_MORE_RESULTS_TO_RETURN result
does *not* indicate a parsing failure, the parse was actually successful; it
does not relate to the outcome of the given operation, and it is not a value
a client would expect to get back from ldap_result2error.

The question is what is the correct result to return - I believe in the case
where ldap_parse_result returns LDAP_MORE_RESULTS_TO_RETURN,
ldap_result_error should be returning the server error code, not the parse
result code.

Comments?

---

From: [email-masked] (Mark C Smith)
Date: Fri, 24 Sep 1999 15:03:10 -0400

First, new applications should avoid ldap_result2error() entirely.  For
maximum compatibility with older applications that do call
ldap_result2error(), I agree with you that it is probably better for
implementations of ldap_result2error() to not return the
LDAP_MORE_RESULTS_TO_RETURN error code.  But these kinds of mappings are
always tricky where the two "interfaces" don't match up very well.  Note
that if ldap_result2error() does not return LDAP_MORE_RESULTS_TO_RETURN,
the information that additional results are present is lost... but an
older client is unlikely to know what to do with that information
anyway.

-- 
Mark Smith
iPlanet Directory Architect / Sun-Netscape Alliance
My words are my own, not my employer's.   Got LDAP?

---

From: "Howard Chu" <[email-masked]>
Date: Fri, 24 Sep 1999 12:27:46 -0700

> From: Mark C Smith [mailto:[email-masked]]

> older client is unlikely to know what to do with that information

Exactly. Yes, I understand perfectly well that ldap_result2error is
deprecated and should not be used in new code. But we all also understand
that there's a lot of old code out there yet to be updated, and until then
a lot of use will be obtained from the backward-compatibility routines. The
point is that returning the LDAP_MORE_RESULTS_TO_RETURN error code simply
isn't backward compatible, and an older client definitely will not know
what to do with it. It will cause error-handling behavior to be invoked in
the client when no failure has actually occurred. In cases like this where
the return code != LDAP_SUCCESS, but ld->ld_errno == LDAP_SUCCESS, the
resulting diagnostic (most likely printed by ldap_perror) will only confuse
people - "why does my client fail and print 'no error' as the error
message?"
All in all a bad thing.

May I suggest, while the new API is still in draft state, that someone make
a pass through and change "function <blah> is deprecated and will not be
discussed here" to say something more helpful like "function <blah> is
deprecated and will not be discussed here *but its full behavior is
documented in RFC 1823*." Then we can unambiguously state that routines
provided for backward compatibility will behave in a consistent, predictable
manner. (And of course we could also say "behaves as in RFC 1823 *except as
follows*" but that would be a bad idea. Best just to faithfully preserve old
behavior.)