]> git.sur5r.net Git - openldap/commitdiff
ITS#7694 Fix use of IPv6 with LDAP_CONNECTIONLESS
authorStef Walter <stefw@redhat.com>
Thu, 12 Sep 2013 13:49:36 +0000 (15:49 +0200)
committerHoward Chu <hyc@openldap.org>
Thu, 10 Oct 2013 17:26:28 +0000 (10:26 -0700)
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

libraries/liblber/sockbuf.c
libraries/libldap/abandon.c
libraries/libldap/open.c
libraries/libldap/os-ip.c
libraries/libldap/request.c
libraries/libldap/result.c
libraries/libldap/search.c

index d997e92910954b943e5b3fe7139ff4caaeaf49bf..858c94204c15e3fb317249a911e730447a37d2db 100644 (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
  * 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
- * must read and write this sockaddr before doing the usual ber_printf/scanf
+ * with a sockaddr_storage containing the address of the remote entity. Upper levels
+ * must read and write this sockaddr_storage before doing the usual ber_printf/scanf
  * 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( buf != NULL );
 
-       addrlen = sizeof( struct sockaddr );
+       addrlen = sizeof( struct sockaddr_storage );
        src = buf;
        buf = (char *) buf + addrlen;
        len -= 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 
@@ -934,11 +934,11 @@ sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
        assert( buf != NULL );
 
        dst = buf;
-       buf = (char *) buf + sizeof( struct sockaddr );
-       len -= sizeof( struct sockaddr );
+       buf = (char *) buf + sizeof( struct sockaddr_storage );
+       len -= sizeof( struct sockaddr_storage );
    
        rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
-               sizeof( struct sockaddr ) );
+               sizeof( struct sockaddr_storage ) );
 
        if ( rc < 0 ) return -1;
    
@@ -949,7 +949,7 @@ sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 # endif
                return -1;
        }
-       rc = len + sizeof(struct sockaddr);
+       rc = len + sizeof(struct sockaddr_storage);
        return rc;
 }
 
index d999b073a11f94d70014a39eb144afccc251f94b..8fd9bc25874f1c1b53f0832cc4557755a289d5b3 100644 (file)
@@ -209,7 +209,7 @@ start_again:;
                        LDAP_NEXT_MSGID(ld, i);
 #ifdef LDAP_CONNECTIONLESS
                        if ( LDAP_IS_UDP(ld) ) {
-                               struct sockaddr sa = {0};
+                               struct sockaddr_storage sa = {0};
                                /* dummy, filled with ldo_peer in request.c */
                                err = ber_write( ber, (char *) &sa, sizeof(sa), 0 );
                        }
index ba10939975986ccb6ada670cffe923ac4ea3969f..ac35e99f3ac49f2eca42de3a3043c8d52c637d70 100644 (file)
@@ -314,8 +314,8 @@ ldap_init_fd(
                LDAP_IS_UDP(ld) = 1;
                if( ld->ld_options.ldo_peer )
                        ldap_memfree( ld->ld_options.ldo_peer );
-               ld->ld_options.ldo_peer = ldap_memalloc( sizeof( struct sockaddr ) );
-               len = sizeof( struct sockaddr );
+               ld->ld_options.ldo_peer = ldap_memcalloc( 1, sizeof( struct sockaddr_storage ) );
+               len = sizeof( struct sockaddr_storage );
                if( getpeername ( fd, ld->ld_options.ldo_peer, &len ) < 0) {
                        ldap_unbind_ext( ld, NULL, NULL );
                        return( AC_SOCKET_ERROR );
index b31e05dc9be58227710e18ed694af6b6c2e14427..90b92dfe63d546f9a2a1c456681f9c0b55cef3be 100644 (file)
@@ -422,8 +422,8 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
        if (LDAP_IS_UDP(ld)) {
                if (ld->ld_options.ldo_peer)
                        ldap_memfree(ld->ld_options.ldo_peer);
-               ld->ld_options.ldo_peer=ldap_memalloc(sizeof(struct sockaddr));
-               AC_MEMCPY(ld->ld_options.ldo_peer,sin,sizeof(struct sockaddr));
+               ld->ld_options.ldo_peer=ldap_memcalloc(1, sizeof(struct sockaddr_storage));
+               AC_MEMCPY(ld->ld_options.ldo_peer,sin,addrlen);
                return ( 0 );
        }
 #endif
index fc2f4d0631b7287eacf3925685720d279cd6c2c8..4822a63432a50425ccc8ef2266b585c794fb7489 100644 (file)
@@ -308,7 +308,7 @@ ldap_send_server_request(
                ber_rewind( &tmpber );
                LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex );
                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 );
                if ( rc == -1 ) {
                        ld->ld_errno = LDAP_ENCODING_ERROR;
index f2a6c7b04c8058e2945dcbbc15640ada67fb2a35..d293299e2a4433d281f6e0b677d2f5ae1374fc58 100644 (file)
@@ -482,8 +482,8 @@ retry:
        sock_errset(0);
 #ifdef LDAP_CONNECTIONLESS
        if ( LDAP_IS_UDP(ld) ) {
-               struct sockaddr from;
-               ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr) );
+               struct sockaddr_storage from;
+               ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr_storage) );
                if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1;
        }
 nextresp3:
index 3867b5b20a5b57f07d63a14f27aab00d61a0b215..b966d1ae49f88f67d01277f2a86bb2caf58b712b 100644 (file)
@@ -305,7 +305,7 @@ ldap_build_search_req(
        LDAP_NEXT_MSGID( ld, *idp );
 #ifdef LDAP_CONNECTIONLESS
        if ( LDAP_IS_UDP(ld) ) {
-               struct sockaddr sa = {0};
+               struct sockaddr_storage sa = {0};
                /* dummy, filled with ldo_peer in request.c */
            err = ber_write( ber, (char *) &sa, sizeof( sa ), 0 );
        }