Finally solved ldapsearch Can't contact LDAP server

Hello
Finally! I found it. This had been bugging me for years. When I made an
ldapsearch that would return hundreds or thousands of entries, I would get
some of the results and then the client would say
Can't contact LDAP server (81)
It would only happen when SASL encryption was turned on.
Digging into how liblber reads encrypted packets, I see that it loads the
encrypted message size first and checks that it's reasonable, then loads
the encrypted message (SASL encoding puts the length as the first 4
bytes).
What I found is that the 4 bytes of the length are loaded in a while()
loop to get all 4 bytes. THE PROBLEM is if the first read comes up short
of 4 bytes, it tries to read the remaining bytes of the quartet, but it
does NOT advance the pointer into which the bytes are read.
The fix is in liblber.c/cyrus.c in sb_sasl_read():
/* Read the length of the packet */
while ( p->sec_buf_in.buf_ptr < 4 ) {
- ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base,
+ ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
+ p->sec_buf_in.buf_ptr,
4 - p->sec_buf_in.buf_ptr );
#ifdef EINTR
if ( ( ret < 0 ) && ( errno == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return bufptr ? bufptr : ret;
p->sec_buf_in.buf_ptr += ret;
}
I think this may be the solution to ITS #1181, #2490, and #2944.
-Mark Adamson
Carnegie Mellon University