Hello all,
I was mucking around with OpenLDAP and noticed that ldap_get_values_len was returning NULL without setting a corresponding error code. Intruiged by this behavior, I did some debugging, and found that it was doing so on nsslapd-referral as generated by a Fedora 1.2.5 or 1.2.6 directory server for the cn=config entry (I haven't checked anywhere else yet). Here is a fragment of the byte sequence in ber_buf that was causing this:
000<14><04><10>nsslapd-referral1<00>0<19><04><12>password
I checked some other code, ldapvi works around this by checking if the return value of ldap_get_values_len is NULL before using it, but it doesn't seem to do so consistently, and an old version of the code had this to say:
struct berval **values = ldap_get_values_len(ld, entry, ad); struct berval **ptr;
if (!values) continue; /* weird server */
I've also posted to 389-users [1], in Fedora Directory Server spitting out malformed data. But in that case, OpenLDAP should give me an error code, or work around it, or something.
Cheers, Edward
[1] http://lists.fedoraproject.org/pipermail/389-users/2010-October/012320.html
Edward Z. Yang wrote:
Hello all,
I was mucking around with OpenLDAP and noticed that ldap_get_values_len was returning NULL without setting a corresponding error code. Intruiged by this behavior, I did some debugging, and found that it was doing so on nsslapd-referral as generated by a Fedora 1.2.5 or 1.2.6 directory server for the cn=config entry (I haven't checked anywhere else yet). Here is a fragment of the byte sequence in ber_buf that was causing this:
000<14><04><10>nsslapd-referral1<00>0<19><04><12>password
I checked some other code, ldapvi works around this by checking if the return value of ldap_get_values_len is NULL before using it, but it doesn't seem to do so consistently, and an old version of the code had this to say:
struct berval **values = ldap_get_values_len(ld, entry, ad); struct berval **ptr; if (!values) continue; /* weird server */
I've also posted to 389-users [1], in Fedora Directory Server spitting out malformed data. But in that case, OpenLDAP should give me an error code, or work around it, or something.
Looking at the code and your data snippet, this is because your BER sequence says it's got a set of zero values. In this case, ber_scanf doesn't bother to allocate any memory to store the values, since there would be no point.
Technically there's no error here; sets are allowed to be empty. (E.g., if you had done an attrsOnly search then all of the attributes would have zero sets for their values.) So no, it's not a bug that libldap returns NULL instead of a pointer. And no, libldap shouldn't report an error code here either.
But it's certainly stupid for the server to attach the attribute to the response with no values, since this is obviously NOT an attrsOnly search response. Sounds like you ought to file a bug report against the Fedora Directory Server.
Cheers, Edward
[1] http://lists.fedoraproject.org/pipermail/389-users/2010-October/012320.html
Hello Howard,
Thank you for your analysis. In this case, I suggest that a note that a NULL may be returned by OpenLDAP by ldap_get_values and ldap_get_values_len, so that programmers are advised they need to special case this non-error condition.
--- ldap_get_values.3 2010-04-13 21:22:39.000000000 +0100 +++ ldap_get_values.3.new 2010-10-18 15:32:49.000000000 +0100 @@ -54,7 +54,9 @@ .B ldap_get_values() takes the \fIentry\fP and the attribute \fIattr\fP whose values are desired and returns a NULL-terminated array of the -attribute's values. \fIattr\fP may be an attribute type as returned +attribute's values. If there are no values to be returned, NULL +may be returned instead (NULL may also indicate an error condition, +see below.) \fIattr\fP may be an attribute type as returned from .BR ldap_first_attribute (3) or
Edward
On 10/18/10 12:48 PM, Howard Chu wrote:
But it's certainly stupid for the server to attach the attribute to the response with no values, since this is obviously NOT an attrsOnly search response.
What about an AttributeType with an OctetString syntax ? It may have an empty value...
Emmanuel Lecharny wrote:
On 10/18/10 12:48 PM, Howard Chu wrote:
But it's certainly stupid for the server to attach the attribute to the response with no values, since this is obviously NOT an attrsOnly search response.
What about an AttributeType with an OctetString syntax ? It may have an empty value...
The function would return a zero-length berval in that case. There's a difference between no values, and one value of zero length.
Excerpts from Howard Chu's message of Mon Oct 18 15:23:02 -0400 2010:
The function would return a zero-length berval in that case. There's a difference between no values, and one value of zero length.
Sure, but for the programmer, there is definitely a difference between p == NULL and *p == NULL. :-)
Cheers, Edward
Edward Z. Yang wrote:
Excerpts from Howard Chu's message of Mon Oct 18 15:23:02 -0400 2010:
The function would return a zero-length berval in that case. There's a difference between no values, and one value of zero length.
Sure, but for the programmer, there is definitely a difference between p == NULL and *p == NULL. :-)
Of course. And again, that's a one-to-one mapping to the difference between no values (p == NULL) and one value of zero-length. Since both conditions are legal in the ASN.1 data, as a programmer you must handle both. (Even though it's nonsensical in this context, and the server is clearly broken.)
openldap-technical@openldap.org