Full_Name: Rein Tollevik Version: 2.4.8 OS: Solaris 10 URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (81.93.160.250)
Below is a patch that fixes, or more correctly works around, a 64bit bug in servers/slapd/syncrepl.c that causes a bus error on (at least) 64bit Solaris. The real problem is imho that libraries/libldap/cyrus.c expects the argument where it should write the LDAP_OPT_X_SASL_* options to be of type ber_len_t and not the sasl_*_t type matching the option value it returns. I.e, the pointer variable where the returns values are written should be cast to the appropriate sasl_*_t type, not a ber_len_t. Writing to a 64bit ber_len_t when the argument is a 32bit sasl_ssf_t causes an alignment error at best case, memory corruption at worst.
I haven't looked too deeply into other cases where LDAP_OPT_X_SASL_* options are set or retrieved with ldap_set_option() or ldap_get_option(), so I don't know the consequence of changing cyrus.c. That's why I don't have what I would consider a real fix to libraries/libldap/cyrus.c rather than this workaround.
Rein Tollevik Basefarm AS
Index: servers/slapd/syncrepl.c =================================================================== RCS file: /f/CVSROOT/drift/OpenLDAP/servers/slapd/syncrepl.c,v retrieving revision 1.1.1.18 diff -u -u -w -r1.1.1.18 syncrepl.c --- servers/slapd/syncrepl.c 21 Feb 2008 13:55:21 -0000 1.1.1.18 +++ servers/slapd/syncrepl.c 7 Mar 2008 11:34:08 -0000 @@ -444,6 +444,10 @@ #ifdef HAVE_TLS void *ssl; #endif + ber_len_t ssf; /* XXX The correct type would be sasl_ssf_t, but + * this is what the LDAP_OPT_X_SASL_SSF return + * value is cast into in libldap/cyrus.c + */
rc = slap_client_connect( &si->si_ld, &si->si_bindconf ); if ( rc != LDAP_SUCCESS ) { @@ -462,7 +466,8 @@ op->o_tls_ssf = ldap_pvt_tls_get_strength( ssl ); } #endif /* HAVE_TLS */ - ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &op->o_sasl_ssf ); + ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &ssf); + op->o_sasl_ssf = ssf; op->o_ssf = ( op->o_sasl_ssf > op->o_tls_ssf ) ? op->o_sasl_ssf : op->o_tls_ssf;