[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#4533) Old request buffer is written to when following referrals
Full_Name: Kalle Svensson
Version: 2.3.20
OS: Solaris 9
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (81.93.143.194)
Hello openLDAP team!
I found a problem related to referrals. The re_encode_reqest() function in
libraries/libldap/request.c is replacing the DN in the original request with the
DN provided in the referral message. It is using ber_scanf()'s in-place format
string directive ("m") to read the original DN, and thus writing a \0 to the
original buffer and destroying the byte following immediately after the DN.
Here is a patch that uses the "o" directive instead:
*** request.c Tue May 9 09:19:08 2006
--- request.c.fixed Tue May 9 09:19:22 2006
***************
*** 1247,1253 ****
ber_int_t scope;
int rc;
BerElement tmpber, *ber;
! struct berval orig_dn;
char *dn;
Debug( LDAP_DEBUG_TRACE,
--- 1247,1253 ----
ber_int_t scope;
int rc;
BerElement tmpber, *ber;
! struct berval *orig_dn;
char *dn;
Debug( LDAP_DEBUG_TRACE,
***************
*** 1270,1287 ****
return( NULL );
}
assert( tag != 0);
if ( tag == LDAP_REQ_BIND ) {
/* bind requests have a version number before the DN & other
stu
ff */
! rtag = ber_scanf( &tmpber, "{im" /*}*/, &ver, &orig_dn );
} else if ( tag == LDAP_REQ_DELETE ) {
/* delete requests don't have a DN wrapping sequence */
! rtag = ber_scanf( &tmpber, "m", &orig_dn );
} else if ( tag == LDAP_REQ_SEARCH ) {
/* search requests need to be re-scope-ed */
! rtag = ber_scanf( &tmpber, "{me" /*"}"*/, &orig_dn, &scope );
if( srv->lud_scope != LDAP_SCOPE_DEFAULT ) {
/* use the scope provided in reference */
--- 1270,1292 ----
return( NULL );
}
+ orig_dn = ( struct berval *) ber_memcalloc( 1, sizeof( struct berval
)
);
+ if ( orig_dn == NULL ) {
+ return( NULL );
+ }
+
assert( tag != 0);
if ( tag == LDAP_REQ_BIND ) {
/* bind requests have a version number before the DN & other
stu
ff */
! rtag = ber_scanf( &tmpber, "{io" /*}*/, &ver, orig_dn );
} else if ( tag == LDAP_REQ_DELETE ) {
/* delete requests don't have a DN wrapping sequence */
! rtag = ber_scanf( &tmpber, "o", orig_dn );
} else if ( tag == LDAP_REQ_SEARCH ) {
/* search requests need to be re-scope-ed */
! rtag = ber_scanf( &tmpber, "{oe" /*"}"*/, orig_dn, &scope );
if( srv->lud_scope != LDAP_SCOPE_DEFAULT ) {
/* use the scope provided in reference */
***************
*** 1310,1332 ****
}
} else {
! rtag = ber_scanf( &tmpber, "{m" /*}*/, &orig_dn );
}
if( rtag == LBER_ERROR ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return NULL;
}
if (( ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
return NULL;
}
if ( srv->lud_dn == NULL ) {
! dn = orig_dn.bv_val;
} else {
! dn = srv->lud_dn;
}
if ( tag == LDAP_REQ_BIND ) {
rc = ber_printf( ber, "{it{is" /*}}*/, msgid, tag, ver, dn );
--- 1315,1340 ----
}
} else {
! rtag = ber_scanf( &tmpber, "{o" /*}*/, orig_dn );
}
if( rtag == LBER_ERROR ) {
+ ber_bvfree( orig_dn );
ld->ld_errno = LDAP_DECODING_ERROR;
return NULL;
}
if (( ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
+ ber_bvfree( orig_dn );
return NULL;
}
if ( srv->lud_dn == NULL ) {
! dn = ber_strdup( orig_dn->bv_val );
} else {
! dn = ber_strdup( srv->lud_dn );
}
+ ber_bvfree( orig_dn );
if ( tag == LDAP_REQ_BIND ) {
rc = ber_printf( ber, "{it{is" /*}}*/, msgid, tag, ver, dn );
***************
*** 1337,1342 ****
--- 1345,1351 ----
} else {
rc = ber_printf( ber, "{it{s" /*}}*/, msgid, tag, dn );
}
+ ber_memfree( dn );
if ( rc == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR;