ITS#7694 Fix use of IPv6 with LDAP_CONNECTIONLESS

LDAP_CONNECTIONLESS code assumed that the size of an peer address
is equal to or smaller than sizeof (struct sockaddr).

Fix to use struct sockaddr_storage instead which is intended for
this purpose. Use getnameinfo() where appropriate so we don't
assume anything about the contents of struct sockaddr
This commit is contained in:
Stef Walter 2013-09-12 15:49:36 +02:00 committed by Howard Chu
parent 63314e9c4a
commit 743a9783d5
7 changed files with 17 additions and 17 deletions

View file

@ -888,8 +888,8 @@ Sockbuf_IO ber_sockbuf_io_debug = {
* *
* All I/O at this level must be atomic. For ease of use, the sb_readahead * All I/O at this level must be atomic. For ease of use, the sb_readahead
* must be used above this module. All data reads and writes are prefixed * must be used above this module. All data reads and writes are prefixed
* with a sockaddr containing the address of the remote entity. Upper levels * with a sockaddr_storage containing the address of the remote entity. Upper levels
* must read and write this sockaddr before doing the usual ber_printf/scanf * must read and write this sockaddr_storage before doing the usual ber_printf/scanf
* operations on LDAP messages. * operations on LDAP messages.
*/ */
@ -914,13 +914,13 @@ sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) ); assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
assert( buf != NULL ); assert( buf != NULL );
addrlen = sizeof( struct sockaddr ); addrlen = sizeof( struct sockaddr_storage );
src = buf; src = buf;
buf = (char *) buf + addrlen; buf = (char *) buf + addrlen;
len -= addrlen; len -= addrlen;
rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen ); rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen );
return rc > 0 ? rc+sizeof(struct sockaddr) : rc; return rc > 0 ? rc+sizeof(struct sockaddr_storage) : rc;
} }
static ber_slen_t static ber_slen_t
@ -934,11 +934,11 @@ sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
assert( buf != NULL ); assert( buf != NULL );
dst = buf; dst = buf;
buf = (char *) buf + sizeof( struct sockaddr ); buf = (char *) buf + sizeof( struct sockaddr_storage );
len -= sizeof( struct sockaddr ); len -= sizeof( struct sockaddr_storage );
rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst, rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
sizeof( struct sockaddr ) ); sizeof( struct sockaddr_storage ) );
if ( rc < 0 ) return -1; if ( rc < 0 ) return -1;
@ -949,7 +949,7 @@ sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
# endif # endif
return -1; return -1;
} }
rc = len + sizeof(struct sockaddr); rc = len + sizeof(struct sockaddr_storage);
return rc; return rc;
} }

View file

@ -209,7 +209,7 @@ start_again:;
LDAP_NEXT_MSGID(ld, i); LDAP_NEXT_MSGID(ld, i);
#ifdef LDAP_CONNECTIONLESS #ifdef LDAP_CONNECTIONLESS
if ( LDAP_IS_UDP(ld) ) { if ( LDAP_IS_UDP(ld) ) {
struct sockaddr sa = {0}; struct sockaddr_storage sa = {0};
/* dummy, filled with ldo_peer in request.c */ /* dummy, filled with ldo_peer in request.c */
err = ber_write( ber, (char *) &sa, sizeof(sa), 0 ); err = ber_write( ber, (char *) &sa, sizeof(sa), 0 );
} }

View file

@ -314,8 +314,8 @@ ldap_init_fd(
LDAP_IS_UDP(ld) = 1; LDAP_IS_UDP(ld) = 1;
if( ld->ld_options.ldo_peer ) if( ld->ld_options.ldo_peer )
ldap_memfree( ld->ld_options.ldo_peer ); ldap_memfree( ld->ld_options.ldo_peer );
ld->ld_options.ldo_peer = ldap_memalloc( sizeof( struct sockaddr ) ); ld->ld_options.ldo_peer = ldap_memcalloc( 1, sizeof( struct sockaddr_storage ) );
len = sizeof( struct sockaddr ); len = sizeof( struct sockaddr_storage );
if( getpeername ( fd, ld->ld_options.ldo_peer, &len ) < 0) { if( getpeername ( fd, ld->ld_options.ldo_peer, &len ) < 0) {
ldap_unbind_ext( ld, NULL, NULL ); ldap_unbind_ext( ld, NULL, NULL );
return( AC_SOCKET_ERROR ); return( AC_SOCKET_ERROR );

View file

@ -422,8 +422,8 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
if (LDAP_IS_UDP(ld)) { if (LDAP_IS_UDP(ld)) {
if (ld->ld_options.ldo_peer) if (ld->ld_options.ldo_peer)
ldap_memfree(ld->ld_options.ldo_peer); ldap_memfree(ld->ld_options.ldo_peer);
ld->ld_options.ldo_peer=ldap_memalloc(sizeof(struct sockaddr)); ld->ld_options.ldo_peer=ldap_memcalloc(1, sizeof(struct sockaddr_storage));
AC_MEMCPY(ld->ld_options.ldo_peer,sin,sizeof(struct sockaddr)); AC_MEMCPY(ld->ld_options.ldo_peer,sin,addrlen);
return ( 0 ); return ( 0 );
} }
#endif #endif

View file

@ -308,7 +308,7 @@ ldap_send_server_request(
ber_rewind( &tmpber ); ber_rewind( &tmpber );
LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex ); LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex );
rc = ber_write( &tmpber, ld->ld_options.ldo_peer, rc = ber_write( &tmpber, ld->ld_options.ldo_peer,
sizeof( struct sockaddr ), 0 ); sizeof( struct sockaddr_storage ), 0 );
LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex ); LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex );
if ( rc == -1 ) { if ( rc == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR; ld->ld_errno = LDAP_ENCODING_ERROR;

View file

@ -482,8 +482,8 @@ retry:
sock_errset(0); sock_errset(0);
#ifdef LDAP_CONNECTIONLESS #ifdef LDAP_CONNECTIONLESS
if ( LDAP_IS_UDP(ld) ) { if ( LDAP_IS_UDP(ld) ) {
struct sockaddr from; struct sockaddr_storage from;
ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr) ); ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr_storage) );
if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1; if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1;
} }
nextresp3: nextresp3:

View file

@ -305,7 +305,7 @@ ldap_build_search_req(
LDAP_NEXT_MSGID( ld, *idp ); LDAP_NEXT_MSGID( ld, *idp );
#ifdef LDAP_CONNECTIONLESS #ifdef LDAP_CONNECTIONLESS
if ( LDAP_IS_UDP(ld) ) { if ( LDAP_IS_UDP(ld) ) {
struct sockaddr sa = {0}; struct sockaddr_storage sa = {0};
/* dummy, filled with ldo_peer in request.c */ /* dummy, filled with ldo_peer in request.c */
err = ber_write( ber, (char *) &sa, sizeof( sa ), 0 ); err = ber_write( ber, (char *) &sa, sizeof( sa ), 0 );
} }