This is a large patch (sorry). Migrate from struct in_addr
authorJeremy Allison <jra@samba.org>
Wed, 24 Oct 2007 21:16:54 +0000 (14:16 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 24 Oct 2007 21:16:54 +0000 (14:16 -0700)
to struct sockaddr_storage in most places that matter (ie.
not the nmbd and NetBIOS lookups). This passes make test
on an IPv4 box, but I'll have to do more work/testing on
IPv6 enabled boxes. This should now give us a framework
for testing and finishing the IPv6 migration. It's at
the state where someone with a working IPv6 setup should
(theorecically) be able to type :
smbclient //ipv6-address/share
and have it work.
Jeremy.
(This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd)

64 files changed:
source3/auth/auth_domain.c
source3/auth/auth_server.c
source3/client/client.c
source3/include/ads.h
source3/include/client.h
source3/include/includes.h
source3/include/smb.h
source3/include/smb_macros.h
source3/lib/interface.c
source3/lib/util_sock.c
source3/lib/util_str.c
source3/libads/kerberos.c
source3/libads/krb5_setpw.c
source3/libads/ldap.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/clidgram.c
source3/libsmb/clikrb5.c
source3/libsmb/libsmbclient.c
source3/libsmb/namecache.c
source3/libsmb/namequery.c
source3/libsmb/namequery_dc.c
source3/libsmb/nmblib.c
source3/libsmb/passchange.c
source3/libsmb/trusts_util.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_become_dmb.c
source3/nmbd/nmbd_browsesync.c
source3/nmbd/nmbd_lmhosts.c
source3/nmbd/nmbd_namelistdb.c
source3/nmbd/nmbd_nameregister.c
source3/nmbd/nmbd_packets.c
source3/nmbd/nmbd_subnetdb.c
source3/nmbd/nmbd_synclists.c
source3/nmbd/nmbd_winsserver.c
source3/nsswitch/winbind_krb5_locator.c
source3/nsswitch/wins.c
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_spoolss_nt.c
source3/rpcclient/rpcclient.c
source3/smbd/change_trust_pw.c
source3/smbd/server.c
source3/torture/locktest.c
source3/torture/masktest.c
source3/torture/torture.c
source3/utils/net.c
source3/utils/net.h
source3/utils/net_ads.c
source3/utils/net_lookup.c
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source3/utils/net_rpc_printer.c
source3/utils/net_time.c
source3/utils/netlookup.c
source3/utils/nmblookup.c
source3/utils/smbcacls.c
source3/utils/smbcquotas.c
source3/web/diagnose.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_rpc.c
source3/winbindd/winbindd_util.c
source3/winbindd/winbindd_wins.c

index 72bdbab182b50f9d206689ace8c429a45fff4bfb..7cddabbbbd0dc67ca050119b17717a2007fd3455 100644 (file)
@@ -42,7 +42,7 @@ extern bool global_machine_password_needs_changing;
 static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
                                                const char *domain,
                                                const char *dc_name,
-                                               struct in_addr dc_ip
+                                               struct sockaddr_storage *dc_ss
                                                struct rpc_pipe_client **pipe_ret,
                                                bool *retry)
 {
@@ -73,7 +73,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
        
        /* Attempt connection */
        *retry = True;
-       result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0, 
+       result = cli_full_connection(cli, global_myname(), dc_name, dc_ss, 0, 
                "IPC$", "IPC", "", "", "", 0, Undefined, retry);
 
        if (!NT_STATUS_IS_OK(result)) {
@@ -183,7 +183,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
                                        uchar chal[8],
                                        auth_serversupplied_info **server_info, 
                                        const char *dc_name,
-                                       struct in_addr dc_ip)
+                                       struct sockaddr_storage *dc_ss)
 
 {
        NET_USER_INFO_3 info3;
@@ -207,7 +207,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
                nt_status = connect_to_domain_password_server(&cli,
                                                        domain,
                                                        dc_name,
-                                                       dc_ip,
+                                                       dc_ss,
                                                        &netlogon_pipe,
                                                        &retry);
        }
@@ -305,7 +305,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        const char *domain = lp_workgroup();
        fstring dc_name;
-       struct in_addr dc_ip;
+       struct sockaddr_storage dc_ss;
 
        if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
                DEBUG(0,("check_ntdomain_security: Configuration error!  Cannot use "
@@ -331,7 +331,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
 
        /* we need our DC to send the net_sam_logon() request to */
 
-       if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
+       if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
                DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n",
                        user_info->domain));
                return NT_STATUS_NO_LOGON_SERVERS;
@@ -343,7 +343,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
                                        (uchar *)auth_context->challenge.data,
                                        server_info,
                                        dc_name,
-                                       dc_ip);
+                                       &dc_ss);
                
        return nt_status;
 }
@@ -377,7 +377,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
        time_t last_change_time;
        DOM_SID sid;
        fstring dc_name;
-       struct in_addr dc_ip;
+       struct sockaddr_storage dc_ss;
 
        if (!user_info || !server_info || !auth_context) {
                DEBUG(1,("check_trustdomain_security: Critical variables not present.  Failing.\n"));
@@ -433,7 +433,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
        /* use get_dc_name() for consistency even through we know that it will be 
           a netbios name */
           
-       if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ip) ) {
+       if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ss) ) {
                DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
                        user_info->domain));
                return NT_STATUS_NO_LOGON_SERVERS;
@@ -445,7 +445,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
                                        (uchar *)auth_context->challenge.data,
                                        server_info,
                                        dc_name,
-                                       dc_ip);
+                                       &dc_ss);
 
        return nt_status;
 }
index 815c1193d14301929c6e17a8d8f276f7470cb021..8b10be93fcae94e544cc481dc8059ba7b4ef51d5 100644 (file)
@@ -33,7 +33,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 {
        struct cli_state *cli = NULL;
        fstring desthost;
-       struct in_addr dest_ip;
+       struct sockaddr_storage dest_ss;
        const char *p;
        char *pserver;
        bool connected_ok = False;
@@ -54,12 +54,12 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
                                   desthost, sizeof(desthost));
                strupper_m(desthost);
 
-               if(!resolve_name( desthost, &dest_ip, 0x20)) {
+               if(!resolve_name( desthost, &dest_ss, 0x20)) {
                        DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
                        continue;
                }
 
-               if (ismyip_v4(dest_ip)) {
+               if (ismyaddr(&dest_ss)) {
                        DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
                        continue;
                }
@@ -73,7 +73,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
                        return NULL;
                }
 
-               status = cli_connect(cli, desthost, &dest_ip);
+               status = cli_connect(cli, desthost, &dest_ss);
                if (NT_STATUS_IS_OK(status)) {
                        DEBUG(3,("connected to password server %s\n",desthost));
                        connected_ok = True;
@@ -91,7 +91,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
        }
        
        if (!attempt_netbios_session_request(&cli, global_myname(), 
-                                            desthost, &dest_ip)) {
+                                            desthost, &dest_ss)) {
                release_server_mutex();
                DEBUG(1,("password server fails session request\n"));
                cli_shutdown(cli);
index f3d454ec4beb9d403bd6e249d308360f2f8d265d..7561ecb6a3e4aec3c6c8d28ec156b57bcd33eea0 100644 (file)
@@ -79,7 +79,7 @@ static bool recurse = False;
 static bool showacls = False;
 bool lowercase = False;
 
-static struct in_addr dest_ip;
+static struct sockaddr_storage dest_ss;
 
 #define SEPARATORS " \t\n\r"
 
@@ -3839,7 +3839,7 @@ static int do_tar_op(char *base_directory)
 
 static int do_message_op(void)
 {
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        struct nmb_name called, calling;
        fstring server_name;
        char name_type_hex[10];
@@ -3853,9 +3853,9 @@ static int do_message_op(void)
        snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
        fstrcat(server_name, name_type_hex);
 
-        zero_ip_v4(&ip);
-       if (have_ip) 
-               ip = dest_ip;
+        zero_addr(&ss,AF_INET);
+       if (have_ip)
+               ss = dest_ss;
 
        /* we can only do messages over port 139 (to windows clients at least) */
 
@@ -3866,7 +3866,7 @@ static int do_message_op(void)
                return 1;
        }
 
-       status = cli_connect(cli, server_name, &ip);
+       status = cli_connect(cli, server_name, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
                return 1;
@@ -3993,12 +3993,12 @@ static int do_message_op(void)
                        break;
                case 'I':
                        {
-                               dest_ip = *interpret_addr2(poptGetOptArg(pc));
-                               if (is_zero_ip_v4(dest_ip))
+                               if (!interpret_string_addr(&dest_ss, poptGetOptArg(pc), 0)) {
                                        exit(1);
+                               }
                                have_ip = True;
 
-                               cli_cm_set_dest_ip( dest_ip );
+                               cli_cm_set_dest_ss(&dest_ss);
                        }
                        break;
                case 'E':
index 37d09f1e4261a1a69241d07e2522924ccfcf2831..a75eaf80fc6e1751b745474cc0d0bd948a557bc0 100644 (file)
@@ -87,7 +87,7 @@ typedef struct ads_struct {
 #ifdef HAVE_LDAP
        struct {
                LDAP *ld;
-               struct in_addr ip; /* the ip of the active connection, if any */
+               struct sockaddr_storage ss; /* the ip of the active connection, if any */
                time_t last_attempt; /* last attempt to reconnect */
                int port;
 
index 597348d162432bddd5d0f78b726c4545cf42a026..c4669dbf2ee7cacb6b5b67f1f1fc43d55b3a49c1 100644 (file)
@@ -112,7 +112,7 @@ struct cli_state {
        struct nmb_name called;
        struct nmb_name calling;
        fstring full_dest_host_name;
-       struct in_addr dest_ip;
+       struct sockaddr_storage dest_ss;
 
        DATA_BLOB secblob; /* cryptkey or negTokenInit */
        uint32 sesskey;
index 0d51c3d049cadbb23e60a071f6aad061171a99cd..fc9e43e55ba401d6dfde5bc897d8d8cc6a15ea59 100644 (file)
@@ -1123,7 +1123,7 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val);
 #endif
 
 /* Samba wrapper function for krb5 functionality. */
-void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
+void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr);
 int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
 int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
index 6d4effda5ea7af393e5956e1594993034d7386d2..4c51acf6f41080572f608c3d8b0f9cb47aa66ec6 100644 (file)
@@ -629,7 +629,7 @@ typedef struct connection_struct {
        char *user; /* name of user who *opened* this connection */
        uid_t uid; /* uid of user who *opened* this connection */
        gid_t gid; /* gid of user who *opened* this connection */
-       char client_address[18]; /* String version of client IP address. */
+       char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */
 
        uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
 
@@ -1850,7 +1850,7 @@ typedef struct _smb_iconv_t {
 
 /* used by the IP comparison function */
 struct ip_service {
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        unsigned port;
 };
 
index aea429d2ea1f3950fa479ca9f357a6aa932a0143..9af63451b07e8421042b73b7359c7ac177537b1d 100644 (file)
@@ -206,11 +206,10 @@ values
         ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
 
 /****************************************************************************
-true if two IP addresses are equal
+true if two IPv4 addresses are equal
 ****************************************************************************/
 
-#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
-#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
+#define ip_equal_v4(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
 
 /*****************************************************************
  splits out the last subkey of a key
index 0696329fd66afd8e4140877cdcc3df7a6aadcc66..49bbceceb78e06053c327b5a6c6fe23dc099c56e 100644 (file)
@@ -269,7 +269,7 @@ const struct sockaddr_storage *iface_ip(const struct sockaddr_storage *ip)
   return True if a IP is directly reachable on one of our interfaces
 */
 
-bool iface_local(struct sockaddr_storage *ip)
+bool iface_local(const struct sockaddr_storage *ip)
 {
        return iface_find(ip, True) ? true : false;
 }
@@ -285,8 +285,7 @@ static void add_interface(const struct iface_struct *ifs)
 
        if (iface_find(&ifs->ip, False)) {
                DEBUG(3,("add_interface: not adding duplicate interface %s\n",
-                       print_sockaddr(addr, sizeof(addr),
-                               &ifs->ip, sizeof(struct sockaddr_storage)) ));
+                       print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
                return;
        }
 
@@ -317,16 +316,13 @@ static void add_interface(const struct iface_struct *ifs)
 
        DEBUG(2,("added interface %s ip=%s ",
                iface->name,
-               print_sockaddr(addr, sizeof(addr),
-                       &iface->ip, sizeof(struct sockaddr_storage)) ));
+               print_sockaddr(addr, sizeof(addr), &iface->ip) ));
        DEBUG(2,("bcast=%s ",
                print_sockaddr(addr, sizeof(addr),
-                       &iface->bcast,
-                       sizeof(struct sockaddr_storage)) ));
+                       &iface->bcast) ));
        DEBUG(2,("netmask=%s\n",
                print_sockaddr(addr, sizeof(addr),
-                       &iface->netmask,
-                       sizeof(struct sockaddr_storage)) ));
+                       &iface->netmask) ));
 }
 
 /****************************************************************************
index c6b1311cf5b8bc494233d22dd28a50f468c4a60b..2d784717b2c2299e23f4a94697d311ee442f9358 100644 (file)
@@ -63,6 +63,27 @@ bool is_ipaddress(const char *str)
        return is_ipaddress_v4(str);
 }
 
+/****************************************************************************
+ Is a sockaddr_storage a broadcast address ? 
+****************************************************************************/
+
+bool is_broadcast_addr(const struct sockaddr_storage *pss)
+{
+#if defined(HAVE_IPV6)
+       if (pss->ss_family == AF_INET6) {
+               const struct in6_addr *sin6 =
+                       &((const struct sockaddr_in6 *)pss)->sin6_addr;
+               return IN6_IS_ADDR_MULTICAST(sin6);
+       }
+#endif
+       if (pss->ss_family == AF_INET) {
+               uint32_t addr =
+               ntohl(((const struct sockaddr_in *)pss)->sin_addr.s_addr);
+               return addr == INADDR_BROADCAST;
+       }
+       return false;
+}
+
 /*******************************************************************
  Wrap getaddrinfo...
 ******************************************************************/
@@ -181,7 +202,7 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
 {
        struct addrinfo *res = NULL;
 
-       memset(pss,'\0', sizeof(*pss));
+       zero_addr(pss, AF_INET);
 
        if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
                return false;
@@ -274,6 +295,17 @@ void zero_ip_v4(struct in_addr *ip)
         *ip = ipzero;
 }
 
+/*******************************************************************
+ Set an address to INADDR_ANY, or IN6ADDR_ANY.
+******************************************************************/
+
+void zero_addr(struct sockaddr_storage *pss, int family)
+{
+       memset(pss, '\0', sizeof(*pss));
+       /* Ensure we're at least a valid sockaddr-storage. */
+       pss->ss_family = family;
+}
+
 /*******************************************************************
  Are two IPs on the same subnet - IPv4 version ?
 ********************************************************************/
@@ -385,7 +417,6 @@ bool addr_equal(const struct sockaddr_storage *ip1,
        return false;
 }
 
-
 /****************************************************************************
  Is an IP address the INADDR_ANY or in6addr_any value ?
 ****************************************************************************/
@@ -417,7 +448,7 @@ bool is_address_any(const struct sockaddr_storage *psa)
  Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
 ****************************************************************************/
 
-char *print_sockaddr(char *dest,
+char *print_sockaddr_len(char *dest,
                        size_t destlen,
                        const struct sockaddr_storage *psa,
                        socklen_t psalen)
@@ -433,6 +464,75 @@ char *print_sockaddr(char *dest,
        return dest;
 }
 
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+                       size_t destlen,
+                       const struct sockaddr_storage *psa)
+{
+       return print_sockaddr_len(dest, destlen, psa, sizeof(*psa));
+}
+
+/****************************************************************************
+ Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+                       const struct sockaddr_storage *pss)
+{
+       char addr[INET6_ADDRSTRLEN];
+       char *dest = NULL;
+       int ret;
+
+       ret = getnameinfo((const struct sockaddr *)pss,
+                       sizeof(struct sockaddr_storage),
+                       addr, sizeof(addr),
+                       NULL, 0,
+                       NI_NUMERICHOST);
+       if (ret) {
+               return NULL;
+       }
+       if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+               /* IPv6 */
+               const struct sockaddr_in6 *sa6 =
+                       (const struct sockaddr_in6 *)pss;
+               uint16_t port = ntohs(sa6->sin6_port);
+
+               if (port) {
+                       dest = talloc_asprintf(ctx,
+                                       "[%s]:%d",
+                                       addr,
+                                       (unsigned int)port);
+               } else {
+                       dest = talloc_asprintf(ctx,
+                                       "[%s]",
+                                       addr);
+               }
+#else
+               return NULL;
+#endif
+       } else {
+               const struct sockaddr_in *sa =
+                       (const struct sockaddr_in *)pss;
+               uint16_t port = ntohs(sa->sin_port);
+
+               if (port) {
+                       dest = talloc_asprintf(ctx,
+                                       "%s:%d",
+                                       addr,
+                                       (unsigned int)port);
+               } else {
+                       dest = talloc_asprintf(ctx,
+                                       "%s",
+                                       addr);
+               }
+       }
+       return dest;
+}
+
 /****************************************************************************
  Set the global client_fd variable.
 ****************************************************************************/
@@ -472,7 +572,7 @@ static const char *get_socket_addr(int fd)
                return addr_buf;
        }
 
-       return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length);
+       return print_sockaddr_len(addr_buf, sizeof(addr_buf), &sa, length);
 }
 
 /****************************************************************************
@@ -1274,24 +1374,26 @@ bool send_smb(int fd, char *buffer)
 ****************************************************************************/
 
 int open_socket_in(int type,
-               int port,
+               uint16_t port,
                int dlevel,
-               uint32 socket_addr, /* NETWORK BYTE ORDER */
-               bool rebind )
+               const struct sockaddr_storage *psock,
+               bool rebind)
 {
-       struct sockaddr_in sock;
+       struct sockaddr_storage sock;
        int res;
 
-       memset( (char *)&sock, '\0', sizeof(sock) );
+       sock = *psock;
 
-#ifdef HAVE_SOCK_SIN_LEN
-       sock.sin_len         = sizeof(sock);
+#if defined(HAVE_IPV6)
+       if (sock.ss_family == AF_INET6) {
+               ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
+       }
 #endif
-       sock.sin_port        = htons( port );
-       sock.sin_family      = AF_INET;
-       sock.sin_addr.s_addr = socket_addr;
+       if (sock.ss_family == AF_INET) {
+               ((struct sockaddr_in *)&sock)->sin_port = htons(port);
+       }
 
-       res = socket( AF_INET, type, 0 );
+       res = socket(sock.ss_family, type, 0 );
        if( res == -1 ) {
                if( DEBUGLVL(0) ) {
                        dbgtext( "open_socket_in(): socket() call failed: " );
@@ -1319,9 +1421,9 @@ int open_socket_in(int type,
                        if( DEBUGLVL( dlevel ) ) {
                                dbgtext( "open_socket_in(): setsockopt: ");
                                dbgtext( "SO_REUSEPORT = %s ",
-                                               val?"true":"false" );
-                               dbgtext( "on port %d failed ", port );
-                               dbgtext( "with error = %s\n", strerror(errno) );
+                                               val?"true":"false");
+                               dbgtext( "on port %d failed ", port);
+                               dbgtext( "with error = %s\n", strerror(errno));
                        }
                }
 #endif /* SO_REUSEPORT */
@@ -1331,17 +1433,18 @@ int open_socket_in(int type,
        if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
                if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
                                port == SMB_PORT2 || port == NMB_PORT) ) {
-                       dbgtext( "bind failed on port %d ", port );
-                       dbgtext( "socket_addr = %s.\n",
-                                       inet_ntoa( sock.sin_addr ) );
-                       dbgtext( "Error = %s\n", strerror(errno) );
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr),
+                                       &sock);
+                       dbgtext( "bind failed on port %d ", port);
+                       dbgtext( "socket_addr = %s.\n", addr);
+                       dbgtext( "Error = %s\n", strerror(errno));
                }
-               close( res );
+               close(res);
                return -1;
        }
 
        DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
-
        return( res );
  }
 
@@ -1349,33 +1452,46 @@ int open_socket_in(int type,
  Create an outgoing socket. timeout is in milliseconds.
 **************************************************************************/
 
-int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
+int open_socket_out(int type,
+               const struct sockaddr_storage *pss,
+               uint16_t port,
+               int timeout)
 {
-       struct sockaddr_in sock_out;
+       char addr[INET6_ADDRSTRLEN];
+       struct sockaddr_storage sock_out = *pss;
        int res,ret;
        int connect_loop = 10;
        int increment = 10;
 
        /* create a socket to write to */
-       res = socket(PF_INET, type, 0);
+       res = socket(pss->ss_family, type, 0);
        if (res == -1) {
                 DEBUG(0,("socket error (%s)\n", strerror(errno)));
                return -1;
        }
 
-       if (type != SOCK_STREAM)
-               return(res);
-
-       memset((char *)&sock_out,'\0',sizeof(sock_out));
-       putip((char *)&sock_out.sin_addr,(char *)addr);
+       if (type != SOCK_STREAM) {
+               return res;
+       }
 
-       sock_out.sin_port = htons( port );
-       sock_out.sin_family = PF_INET;
+#if defined(HAVE_IPV6)
+       if (pss->ss_family == AF_INET6) {
+               struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out;
+               psa6->sin6_port = htons(port);
+       }
+#endif
+       if (pss->ss_family == AF_INET) {
+               struct sockaddr_in *psa = (struct sockaddr_in *)&sock_out;
+               psa->sin_port = htons(port);
+       }
 
        /* set it non-blocking */
        set_blocking(res,false);
 
-       DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
+       print_sockaddr(addr, sizeof(addr), &sock_out);
+       DEBUG(3,("Connecting to %s at port %u\n",
+                               addr,
+                               (unsigned int)port));
 
        /* and connect it to the destination */
   connect_again:
@@ -1397,8 +1513,9 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
 
        if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
                        errno == EAGAIN)) {
-               DEBUG(1,("timeout connecting to %s:%d\n",
-                                       inet_ntoa(*addr),port));
+               DEBUG(1,("timeout connecting to %s:%u\n",
+                                       addr,
+                                       (unsigned int)port));
                close(res);
                return -1;
        }
@@ -1412,7 +1529,9 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
 
        if (ret < 0) {
                DEBUG(2,("error connecting to %s:%d (%s)\n",
-                               inet_ntoa(*addr),port,strerror(errno)));
+                               addr,
+                               (unsigned int)port,
+                               strerror(errno)));
                close(res);
                return -1;
        }
@@ -1429,7 +1548,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
  of DC's all of which are equivalent for our purposes.
 **************************************************************************/
 
-bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
+bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
                         int timeout, int *fd_index, int *fd)
 {
        int i, resulting_index, res;
@@ -1455,7 +1574,7 @@ bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
                sockets[i] = -1;
 
        for (i=0; i<num_addrs; i++) {
-               sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
+               sockets[i] = socket(addrs[i].ss_family, SOCK_STREAM, 0);
                if (sockets[i] < 0)
                        goto done;
                set_blocking(sockets[i], false);
@@ -1639,7 +1758,7 @@ static const char *get_peer_addr_internal(int fd,
                return addr_buf;
        }
 
-       print_sockaddr(addr_buf,
+       print_sockaddr_len(addr_buf,
                        sizeof(addr_buf),
                        pss,
                        *plength);
@@ -1705,7 +1824,7 @@ static bool matchname(const char *remotehost,
         */
 
        DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
-               print_sockaddr(addr_buf,
+               print_sockaddr_len(addr_buf,
                        sizeof(addr_buf),
                        pss,
                        len),
@@ -2004,8 +2123,7 @@ bool is_myname_or_ipaddr(const char *s)
                if (interpret_string_addr(&ss, servername,0)) {
                        print_sockaddr(name,
                                        sizeof(name),
-                                       &ss,
-                                       sizeof(ss));
+                                       &ss);
                        servername = name;
                }
        }
index 2fd22280a4b512cfd1099aeef4c3183b5ea8b3f6..226bf826fbe98d2e34df8ab748c40dd3652c1959 100644 (file)
@@ -2270,27 +2270,54 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert)
  *         reallocated to new length
  **/
 
-char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
+static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
 {
        char *new_ipstr = NULL;
+       char addr_buf[INET6_ADDRSTRLEN];
 
        /* arguments checking */
-       if (!ipstr_list || !service) return NULL;
+       if (!ipstr_list || !service) {
+               return NULL;
+       }
 
        /* attempt to convert ip to a string and append colon separator to it */
        if (*ipstr_list) {
-               asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
-                       inet_ntoa(service->ip), service->port);
+               print_sockaddr(addr_buf,
+                               sizeof(addr_buf),
+                               &service->ss);
+               if (service->ss.ss_family == AF_INET) {
+                       /* IPv4 */
+                       asprintf(&new_ipstr, "%s%s%s:%d",
+                                       *ipstr_list,
+                                       IPSTR_LIST_SEP,
+                                       addr_buf,
+                                       service->port);
+               } else {
+                       /* IPv6 */
+                       asprintf(&new_ipstr, "%s%s[%s]:%d",
+                                       *ipstr_list,
+                                       IPSTR_LIST_SEP,
+                                       addr_buf,
+                                       service->port);
+               }
                SAFE_FREE(*ipstr_list);
        } else {
-               asprintf(&new_ipstr, "%s:%d",
-                               inet_ntoa(service->ip), service->port);
+               if (service->ss.ss_family == AF_INET) {
+                       /* IPv4 */
+                       asprintf(&new_ipstr, "%s:%d",
+                               addr_buf,
+                               service->port);
+               } else {
+                       /* IPv6 */
+                       asprintf(&new_ipstr, "[%s]:%d",
+                               addr_buf,
+                               service->port);
+               }
        }
        *ipstr_list = new_ipstr;
        return *ipstr_list;
 }
 
-
 /**
  * Allocate and initialise an ipstr list using ip adresses
  * passed as arguments.
@@ -2302,18 +2329,22 @@ char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
  **/
 
 char *ipstr_list_make(char **ipstr_list,
-               const struct ip_service * ip_list, int ip_count)
+                       const struct ip_service *ip_list,
+                       int ip_count)
 {
        int i;
 
        /* arguments checking */
-       if (!ip_list || !ipstr_list) return 0;
+       if (!ip_list || !ipstr_list) {
+               return 0;
+       }
 
        *ipstr_list = NULL;
 
        /* process ip addresses given as arguments */
-       for (i = 0; i < ip_count; i++)
+       for (i = 0; i < ip_count; i++) {
                *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
+       }
 
        return (*ipstr_list);
 }
@@ -2322,7 +2353,7 @@ char *ipstr_list_make(char **ipstr_list,
 /**
  * Parse given ip string list into array of ip addresses
  * (as ip_service structures)
- *    e.g. 192.168.1.100:389,192.168.1.78, ...
+ *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
  *
  * @param ipstr ip string list to be parsed
  * @param ip_list pointer to array of ip addresses which is
@@ -2330,7 +2361,7 @@ char *ipstr_list_make(char **ipstr_list,
  * @return number of succesfully parsed addresses
  **/
 
-int ipstr_list_parse(const charipstr_list, struct ip_service **ip_list)
+int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
 {
        fstring token_str;
        size_t count;
@@ -2348,27 +2379,34 @@ int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
 
        for ( i=0; next_token(&ipstr_list, token_str,
                                IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
-               struct in_addr addr;
-               unsigned port = 0;
-               char *p = strchr(token_str, ':');
+               char *s = token_str;
+               char *p = strrchr(token_str, ':');
 
                if (p) {
                        *p = 0;
-                       port = atoi(p+1);
+                       (*ip_list)[i].port = atoi(p+1);
                }
 
                /* convert single token to ip address */
-               if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
-                       break;
-
-               (*ip_list)[i].ip = addr;
-               (*ip_list)[i].port = port;
+               if (token_str[0] == '[') {
+                       /* IPv6 address. */
+                       s++;
+                       p = strchr(token_str, ']');
+                       if (!p) {
+                               continue;
+                       }
+                       *p = '\0';
+               }
+               if (!interpret_string_addr(&(*ip_list)[i].ss,
+                                       s,
+                                       AI_NUMERICHOST)) {
+                       continue;
+               }
        }
 
        return count;
 }
 
-
 /**
  * Safely free ip string list
  *
@@ -2380,7 +2418,6 @@ void ipstr_list_free(char* ipstr_list)
        SAFE_FREE(ipstr_list);
 }
 
-
 /**
  Unescape a URL encoded string, in place.
 **/
index 281ca2fd6836fdd513eb478b6f04bf004ab4b566..f259c21bdb4698a1d2b503c2e68c97f17f810e51 100644 (file)
@@ -614,7 +614,10 @@ int kerberos_kinit_password(const char *principal,
  Does DNS queries.
 ************************************************************************/
 
-static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip)
+static char *get_kdc_ip_string(char *mem_ctx,
+               const char *realm,
+               const char *sitename,
+               struct sockaddr_storage *pss)
 {
        int i;
        struct ip_service *ip_srv_site = NULL;
@@ -622,7 +625,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit
        int count_site = 0;
        int count_nonsite;
        char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n",
-                                       inet_ntoa(primary_ip));
+                                       print_canonical_sockaddr(mem_ctx,
+                                                       pss));
 
        if (kdc_str == NULL) {
                return NULL;
@@ -635,12 +639,15 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit
                get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
 
                for (i = 0; i < count_site; i++) {
-                       if (ip_equal(ip_srv_site[i].ip, primary_ip)) {
+                       if (addr_equal(&ip_srv_site[i].ss, pss)) {
                                continue;
                        }
-                       /* Append to the string - inefficient but not done often. */
+                       /* Append to the string - inefficient
+                        * but not done often. */
                        kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
-                               kdc_str, inet_ntoa(ip_srv_site[i].ip));
+                               kdc_str,
+                               print_canonical_sockaddr(mem_ctx,
+                                                       &ip_srv_site[i].ss));
                        if (!kdc_str) {
                                SAFE_FREE(ip_srv_site);
                                return NULL;
@@ -655,13 +662,14 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit
        for (i = 0; i < count_nonsite; i++) {
                int j;
 
-               if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) {
+               if (addr_equal(&ip_srv_nonsite[i].ss, pss)) {
                        continue;
                }
 
                /* Ensure this isn't an IP already seen (YUK! this is n*n....) */
                for (j = 0; j < count_site; j++) {
-                       if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) {
+                       if (addr_equal(&ip_srv_nonsite[i].ss,
+                                               &ip_srv_site[j].ss)) {
                                break;
                        }
                        /* As the lists are sorted we can break early if nonsite > site. */
@@ -675,7 +683,9 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit
 
                /* Append to the string - inefficient but not done often. */
                kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
-                       kdc_str, inet_ntoa(ip_srv_nonsite[i].ip));
+                               kdc_str,
+                               print_canonical_sockaddr(mem_ctx,
+                                               &ip_srv_nonsite[i].ss));
                if (!kdc_str) {
                        SAFE_FREE(ip_srv_site);
                        SAFE_FREE(ip_srv_nonsite);
@@ -700,8 +710,10 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit
  run as root or will fail (which is a good thing :-).
 ************************************************************************/
 
-bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain,
-                                       const char *sitename, struct in_addr ip)
+bool create_local_private_krb5_conf_for_domain(const char *realm,
+                                               const char *domain,
+                                               const char *sitename,
+                                               struct sockaddr_storage *pss)
 {
        char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir());
        char *tmpname = NULL;
@@ -742,12 +754,12 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do
        realm_upper = talloc_strdup(fname, realm);
        strupper_m(realm_upper);
 
-       kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip);
+       kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss);
        if (!kdc_ip_string) {
                TALLOC_FREE(dname);
                return False;
        }
-               
+
        file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n"
                                "[realms]\n\t%s = {\n"
                                "\t%s\t}\n",
@@ -806,7 +818,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do
 
        DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote "
                "file %s with realm %s KDC = %s\n",
-               fname, realm_upper, inet_ntoa(ip) ));
+               fname, realm_upper, print_canonical_sockaddr(dname, pss) ));
 
        /* Set the environment variable to this file. */
        setenv("KRB5_CONFIG", fname, 1);
index 73dffe7c1bd306f2db1ddebae170bc198cded8f2..831a44884701dfa93a32f6c6e5057804ac1de9c7 100644 (file)
@@ -402,11 +402,14 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
        int ret, sock;
        socklen_t addr_len;
        struct sockaddr remote_addr, local_addr;
-       struct in_addr *addr = interpret_addr2(kdc_host);
+       struct sockaddr_storage addr;
        krb5_address local_kaddr, remote_kaddr;
        bool use_tcp = False;
 
 
+       if (!interpret_string_addr(&addr, kdc_host, 0)) {
+       }
+
        ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
                                   NULL, credsp, &ap_req);
        if (ret) {
@@ -422,7 +425,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
 
                } else {
 
-                       sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, 
+                       sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT, 
                                               LONG_CONNECT_TIMEOUT);
                }
 
@@ -430,18 +433,29 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
                        int rc = errno;
                        SAFE_FREE(ap_req.data);
                        krb5_auth_con_free(context, auth_context);
-                       DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", 
+                       DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
                                 kdc_host, strerror(errno)));
                        return ADS_ERROR_SYSTEM(rc);
                }
-               
                addr_len = sizeof(remote_addr);
                getpeername(sock, &remote_addr, &addr_len);
                addr_len = sizeof(local_addr);
                getsockname(sock, &local_addr, &addr_len);
-               
-               setup_kaddr(&remote_kaddr, &remote_addr);
-               setup_kaddr(&local_kaddr, &local_addr);
+
+               /* FIXME ! How do we do IPv6 here ? JRA. */
+               if (remote_addr.sa_family != AF_INET ||
+                               local_addr.sa_family != AF_INET) {
+                       DEBUG(1,("do_krb5_kpasswd_request: "
+                               "no IPv6 support (yet).\n"));
+                       close(sock);
+                       SAFE_FREE(ap_req.data);
+                       krb5_auth_con_free(context, auth_context);
+                       errno = EINVAL;
+                       return ADS_ERROR_SYSTEM(EINVAL);
+               }
+
+               setup_kaddr_v4(&remote_kaddr, &remote_addr);
+               setup_kaddr_v4(&local_kaddr, &local_addr);
        
                ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
                if (ret) {
index f85d3cd7b0c572ecd825aa5ed2a4cf2389875443..0294c4a5b5fbab9125def9b8e645737a568dff4d 100644 (file)
@@ -221,13 +221,19 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server )
                ads->config.client_site_name =
                        SMB_STRDUP(cldap_reply.client_site_name);
        }
-               
        ads->server.workgroup          = SMB_STRDUP(cldap_reply.netbios_domain);
 
        ads->ldap.port = LDAP_PORT;
-       ads->ldap.ip = *interpret_addr2(srv);
+       if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) {
+               DEBUG(1,("ads_try_connect: unable to convert %s "
+                       "to an address\n",
+                       srv));
+               SAFE_FREE( srv );
+               return False;
+       }
+
        SAFE_FREE(srv);
-       
+
        /* Store our site name. */
        sitename_store( cldap_reply.domain, cldap_reply.client_site_name );
 
@@ -306,10 +312,10 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 
        /* if we fail this loop, then giveup since all the IP addresses returned were dead */
        for ( i=0; i<count; i++ ) {
-               fstring server;
-               
-               fstrcpy( server, inet_ntoa(ip_list[i].ip) );
-               
+               char server[INET6_ADDRSTRLEN];
+
+               print_sockaddr(server, sizeof(server), &ip_list[i].ss);
+
                if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
                        continue;
 
@@ -371,6 +377,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
        int version = LDAP_VERSION3;
        ADS_STATUS status;
        NTSTATUS ntstatus;
+       char addr[INET6_ADDRSTRLEN];
 
        ZERO_STRUCT(ads->ldap);
        ads->ldap.last_attempt  = time(NULL);
@@ -378,7 +385,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 
        /* try with a user specified server */
 
-       if (ads->server.ldap_server && 
+       if (ads->server.ldap_server &&
            ads_try_connect(ads, ads->server.ldap_server)) {
                goto got_connection;
        }
@@ -391,7 +398,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
        return ADS_ERROR_NT(ntstatus);
 
 got_connection:
-       DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip)));
+
+       print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+       DEBUG(3,("Connected to LDAP server %s\n", addr));
 
        if (!ads->auth.user_name) {
                /* Must use the userPrincipalName value here or sAMAccountName
@@ -405,7 +414,8 @@ got_connection:
        }
 
        if (!ads->auth.kdc_server) {
-               ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip));
+               print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+               ads->auth.kdc_server = SMB_STRDUP(addr);
        }
 
 #if KRB5_DNS_HACK
@@ -440,8 +450,9 @@ got_connection:
 
        /* cache the successful connection for workgroup and realm */
        if (ads_closest_dc(ads)) {
-               saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip));
-               saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip));
+               print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+               saf_store( ads->server.workgroup, addr);
+               saf_store( ads->server.realm, addr);
        }
 
        ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version);
index 82cd6d6d137f23f17657fbab258d0709ee5f3cad..826315ad7a66cc8de080556c7abc4bb1fd4c3851 100644 (file)
@@ -1366,11 +1366,17 @@ bool cli_session_request(struct cli_state *cli,
                int16 port;
                };
                */
-               int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+               uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+               struct in_addr dest_ip;
+
                /* SESSION RETARGET */
-               putip((char *)&cli->dest_ip,cli->inbuf+4);
+               putip((char *)&dest_ip,cli->inbuf+4);
+               in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
 
-               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
+               cli->fd = open_socket_out(SOCK_STREAM,
+                               &cli->dest_ss,
+                               port,
+                               LONG_CONNECT_TIMEOUT);
                if (cli->fd == -1)
                        return False;
 
@@ -1405,49 +1411,61 @@ bool cli_session_request(struct cli_state *cli,
  Open the client sockets.
 ****************************************************************************/
 
-NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
+NTSTATUS cli_connect(struct cli_state *cli,
+               const char *host,
+               struct sockaddr_storage *dest_ss)
+
 {
        int name_type = 0x20;
        char *p;
 
        /* reasonable default hostname */
-       if (!host) host = "*SMBSERVER";
+       if (!host) {
+               host = "*SMBSERVER";
+       }
 
        fstrcpy(cli->desthost, host);
 
        /* allow hostnames of the form NAME#xx and do a netbios lookup */
        if ((p = strchr(cli->desthost, '#'))) {
-               name_type = strtol(p+1, NULL, 16);              
+               name_type = strtol(p+1, NULL, 16);
                *p = 0;
        }
-       
-       if (!ip || is_zero_ip_v4(*ip)) {
-                if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
+
+       if (!dest_ss || is_zero_addr(dest_ss)) {
+                if (!resolve_name(cli->desthost, &cli->dest_ss, name_type)) {
                        return NT_STATUS_BAD_NETWORK_NAME;
                 }
-               if (ip) *ip = cli->dest_ip;
+               if (dest_ss) {
+                       *dest_ss = cli->dest_ss;
+               }
        } else {
-               cli->dest_ip = *ip;
+               cli->dest_ss = *dest_ss;
        }
 
        if (getenv("LIBSMB_PROG")) {
                cli->fd = sock_exec(getenv("LIBSMB_PROG"));
        } else {
                /* try 445 first, then 139 */
-               int port = cli->port?cli->port:445;
-               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
+               uint16_t port = cli->port?cli->port:445;
+               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
                                          port, cli->timeout);
                if (cli->fd == -1 && cli->port == 0) {
                        port = 139;
-                       cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
+                       cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
                                                  port, cli->timeout);
                }
-               if (cli->fd != -1)
+               if (cli->fd != -1) {
                        cli->port = port;
+               }
        }
        if (cli->fd == -1) {
+               char addr[INET6_ADDRSTRLEN];
+               if (dest_ss) {
+                       print_sockaddr(addr, sizeof(addr), dest_ss);
+               }
                DEBUG(1,("Error connecting to %s (%s)\n",
-                        ip?inet_ntoa(*ip):host,strerror(errno)));
+                        dest_ss?addr:host,strerror(errno)));
                return map_nt_error_from_unix(errno);
        }
 
@@ -1460,7 +1478,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip
    establishes a connection to after the negprot. 
    @param output_cli A fully initialised cli structure, non-null only on success
    @param dest_host The netbios name of the remote host
-   @param dest_ip (optional) The the destination IP, NULL for name based lookup
+   @param dest_ss (optional) The the destination IP, NULL for name based lookup
    @param port (optional) The destination port (0 for default)
    @param retry bool. Did this connection fail with a retryable error ?
 
@@ -1468,7 +1486,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip
 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
                              const char *my_name, 
                              const char *dest_host, 
-                             struct in_addr *dest_ip, int port,
+                             struct sockaddr_storage *dest_ss, int port,
                              int signing_state, int flags,
                              bool *retry) 
 {
@@ -1476,7 +1494,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
        struct nmb_name calling;
        struct nmb_name called;
        struct cli_state *cli;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
 
        if (retry)
                *retry = False;
@@ -1498,19 +1516,22 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
 
        cli_set_timeout(cli, 10000); /* 10 seconds. */
 
-       if (dest_ip)
-               ip = *dest_ip;
-       else
-               ZERO_STRUCT(ip);
+       if (dest_ss) {
+               ss = *dest_ss;
+       } else {
+               zero_addr(&ss, AF_INET);
+       }
 
 again:
 
        DEBUG(3,("Connecting to host=%s\n", dest_host));
-       
-       nt_status = cli_connect(cli, dest_host, &ip);
+
+       nt_status = cli_connect(cli, dest_host, &ss);
        if (!NT_STATUS_IS_OK(nt_status)) {
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &ss);
                DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
-                        nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) ));
+                        nmb_namestr(&called), addr, nt_errstr(nt_status) ));
                cli_shutdown(cli);
                return nt_status;
        }
@@ -1520,9 +1541,9 @@ again:
 
        if (!cli_session_request(cli, &calling, &called)) {
                char *p;
-               DEBUG(1,("session request to %s failed (%s)\n", 
+               DEBUG(1,("session request to %s failed (%s)\n",
                         called.name, cli_errstr(cli)));
-               if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) {
+               if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
                        *p = 0;
                        goto again;
                }
@@ -1572,7 +1593,7 @@ again:
 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
                             const char *my_name, 
                             const char *dest_host, 
-                            struct in_addr *dest_ip, int port,
+                            struct sockaddr_storage *dest_ss, int port,
                             const char *service, const char *service_type,
                             const char *user, const char *domain, 
                             const char *password, int flags,
@@ -1589,9 +1610,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
                password = "";
        }
 
-       nt_status = cli_start_connection(&cli, my_name, dest_host, 
-                                        dest_ip, port, signing_state, flags, retry);
-       
+       nt_status = cli_start_connection(&cli, my_name, dest_host,
+                                        dest_ss, port, signing_state,
+                                        flags, retry);
+
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -1615,7 +1637,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
                        return nt_status;
                }
        }
-       
+
        if (service) {
                if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
                        nt_status = cli_nt_error(cli);
@@ -1639,7 +1661,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
 ****************************************************************************/
 
 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
-                                     struct in_addr *pdest_ip)
+                                     struct sockaddr_storage *pdest_ss)
 {
        struct nmb_name calling, called;
 
@@ -1650,7 +1672,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
         * then use *SMBSERVER immediately.
         */
 
-       if(is_ipaddress_v4(desthost)) {
+       if(is_ipaddress(desthost)) {
                make_nmb_name(&called, "*SMBSERVER", 0x20);
        } else {
                make_nmb_name(&called, desthost, 0x20);
@@ -1687,7 +1709,7 @@ with error %s.\n", desthost, cli_errstr(*ppcli) ));
                        return False;
                }
 
-               status = cli_connect(*ppcli, desthost, pdest_ip);
+               status = cli_connect(*ppcli, desthost, pdest_ss);
                if (!NT_STATUS_IS_OK(status) ||
                                !cli_session_request(*ppcli, &calling, &smbservername)) {
                        DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
@@ -1699,10 +1721,6 @@ name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
        return True;
 }
 
-
-
-
-
 /****************************************************************************
  Send an old style tcon.
 ****************************************************************************/
@@ -1749,27 +1767,28 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli,
 
 /* Return a cli_state pointing at the IPC$ share for the given server */
 
-struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
-                                         struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect(char *server,
+                               struct sockaddr_storage *server_ss,
+                               struct user_auth_info *user_info)
 {
         struct cli_state *cli;
         pstring myname;
        NTSTATUS nt_status;
 
         get_myname(myname);
-       
-       nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", 
+
+       nt_status = cli_full_connection(&cli, myname, server, server_ss, 0, "IPC$", "IPC", 
                                        user_info->username, lp_workgroup(), user_info->password, 
                                        CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL);
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
-       } else if (is_ipaddress_v4(server)) {
+       } else if (is_ipaddress(server)) {
            /* windows 9* needs a correct NMB name for connections */
            fstring remote_name;
 
-           if (name_status_find("*", 0, 0, *server_ip, remote_name)) {
-               cli = get_ipc_connect(remote_name, server_ip, user_info);
+           if (name_status_find("*", 0, 0, server_ss, remote_name)) {
+               cli = get_ipc_connect(remote_name, server_ss, user_info);
                if (cli)
                    return cli;
            }
@@ -1789,14 +1808,16 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
  * entire network browse list)
  */
 
-struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info)
 {
+       char addr[INET6_ADDRSTRLEN];
         static fstring name;
        struct cli_state *cli;
-       struct in_addr server_ip; 
+       struct sockaddr_storage server_ss;
 
+       print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
         DEBUG(99, ("Looking up name of master browser %s\n",
-                   inet_ntoa(mb_ip->ip)));
+                   addr));
 
         /*
          * Do a name status query to find out the name of the master browser.
@@ -1809,28 +1830,27 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring w
          * the original wildcard query as the first choice and fall back to
          * MSBROWSE if the wildcard query fails.
          */
-        if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) &&
-            !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) {
+        if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
+            !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
 
                 DEBUG(99, ("Could not retrieve name status for %s\n",
-                           inet_ntoa(mb_ip->ip)));
+                           addr));
                 return NULL;
         }
 
-        if (!find_master_ip(name, &server_ip)) {
+        if (!find_master_ip(name, &server_ss)) {
                 DEBUG(99, ("Could not find master ip for %s\n", name));
                 return NULL;
         }
 
-                pstrcpy(workgroup, name);
+       pstrcpy(workgroup, name);
 
-                DEBUG(4, ("found master browser %s, %s\n", 
-                  name, inet_ntoa(mb_ip->ip)));
+       DEBUG(4, ("found master browser %s, %s\n", name, addr));
 
-               cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
+       print_sockaddr(addr, sizeof(addr), &server_ss);
+       cli = get_ipc_connect(addr, &server_ss, user_info);
 
-               return cli;
-    
+       return cli;
 }
 
 /*
@@ -1846,7 +1866,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
 
         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
 
-        /* Go looking for workgroups by broadcasting on the local network */ 
+        /* Go looking for workgroups by broadcasting on the local network */
 
         if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
                                                &count))) {
@@ -1855,11 +1875,13 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
         }
 
        for (i = 0; i < count; i++) {
-            DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+               DEBUG(99, ("Found master browser %s\n", addr));
 
-            cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
-            if (cli)
-                    return(cli);
+               cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
+               if (cli)
+                       return(cli);
        }
 
        return NULL;
index f7bf8506fe8b1b21b047054b09daaf30f33a2ee8..e1ca924b0925ab8045ea52a523ddc87d83aa2b97 100644 (file)
@@ -50,7 +50,7 @@ int max_protocol = PROTOCOL_NT1;
 static int port;
 static int name_type = 0x20;
 static bool have_ip;
-static struct in_addr dest_ip;
+static struct sockaddr_storage dest_ss;
 
 static struct client_connection *connections;
 
@@ -64,7 +64,7 @@ static struct cli_state *do_connect( const char *server, const char *share,
        struct cli_state *c = NULL;
        struct nmb_name called, calling;
        const char *server_n;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        pstring servicename;
        char *sharename;
        fstring newserver, newshare;
@@ -83,22 +83,22 @@ static struct cli_state *do_connect( const char *server, const char *share,
 
        server_n = server;
        
-       zero_ip_v4(&ip);
+       zero_addr(&ss, AF_INET);
 
        make_nmb_name(&calling, global_myname(), 0x0);
        make_nmb_name(&called , server, name_type);
 
  again:
-       zero_ip_v4(&ip);
-       if (have_ip) 
-               ip = dest_ip;
+       zero_addr(&ss, AF_INET);
+       if (have_ip)
+               ss = dest_ss;
 
        /* have to open a new connection */
        if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
                d_printf("Connection to %s failed\n", server_n);
                return NULL;
        }
-       status = cli_connect(c, server_n, &ip);
+       status = cli_connect(c, server_n, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status));
                return NULL;
@@ -366,10 +366,10 @@ void cli_cm_set_dest_name_type( int type )
 /****************************************************************************
 ****************************************************************************/
 
-void cli_cm_set_dest_ip(struct in_addr ip )
+void cli_cm_set_dest_ss(struct sockaddr_storage *pss)
 {
-       dest_ip = ip;
-       have_ip = True;
+       dest_ss = *pss;
+       have_ip = true;
 }
 
 /**********************************************************************
index 4fc9243b5b838e338e33c7122c2d4e2acda39dc0..9f6f4480c5e27453f173558e27f9655e85231904 100644 (file)
@@ -29,21 +29,27 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx,
                       bool unique, const char *mailslot,
                       uint16 priority,
                       char *buf, int len,
-                      const char *srcname, int src_type, 
+                      const char *srcname, int src_type,
                       const char *dstname, int dest_type,
-                      struct in_addr dest_ip)
+                      const struct sockaddr_storage *dest_ss)
 {
        struct packet_struct p;
        struct dgram_packet *dgram = &p.packet.dgram;
        char *ptr, *p2;
        char tmp[4];
        pid_t nmbd_pid;
+       char addr[INET6_ADDRSTRLEN];
 
        if ((nmbd_pid = pidfile_pid("nmbd")) == 0) {
                DEBUG(3, ("No nmbd found\n"));
                return False;
        }
 
+       if (dest_ss->ss_family != AF_INET) {
+               DEBUG(3, ("cli_send_mailslot: can't send to IPv6 address.\n"));
+               return false;
+       }
+
        memset((char *)&p, '\0', sizeof(p));
 
        /*
@@ -51,7 +57,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx,
         */
 
        /* DIRECT GROUP or UNIQUE datagram. */
-       dgram->header.msg_type = unique ? 0x10 : 0x11; 
+       dgram->header.msg_type = unique ? 0x10 : 0x11;
        dgram->header.flags.node_type = M_NODE;
        dgram->header.flags.first = True;
        dgram->header.flags.more = False;
@@ -60,7 +66,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx,
        /* source ip is filled by nmbd */
        dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
        dgram->header.packet_offset = 0;
-  
+
        make_nmb_name(&dgram->source_name,srcname,src_type);
        make_nmb_name(&dgram->dest_name,dstname,dest_type);
 
@@ -93,13 +99,14 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx,
        dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
 
        p.packet_type = DGRAM_PACKET;
-       p.ip = dest_ip;
+       p.ip = ((const struct sockaddr_in *)&dest_ss)->sin_addr;
        p.timestamp = time(NULL);
 
        DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ",
                 mailslot, nmb_namestr(&dgram->source_name)));
-       DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name),
-                   inet_ntoa(dest_ip)));
+       print_sockaddr(addr, sizeof(addr), dest_ss);
+
+       DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), addr));
 
        return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx,
                                                  pid_to_procid(nmbd_pid),
@@ -136,9 +143,9 @@ int cli_get_backup_list(struct messaging_context *msg_ctx,
 {
        pstring outbuf;
        char *p;
-       struct in_addr sendto_ip;
+       struct sockaddr_storage sendto_ss;
 
-       if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) {
+       if (!resolve_name(send_to_name, &sendto_ss, 0x1d)) {
 
                DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name));
                return False;
@@ -161,7 +168,7 @@ int cli_get_backup_list(struct messaging_context *msg_ctx,
 
        cli_send_mailslot(msg_ctx, True, "\\MAILSLOT\\BROWSE", 1, outbuf, 
                          PTR_DIFF(p, outbuf), myname, 0, send_to_name, 
-                         0x1d, sendto_ip);
+                         0x1d, &sendto_ss);
 
        /* We should check the error and return if we got one */
 
index 42918347975e56b46c477b68658a37466324cfe6..fb25e9e20382f77581b343e6747edd213c9431c2 100644 (file)
@@ -162,7 +162,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context,
 
 #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS)
 /* HEIMDAL */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
+ void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr)
 {
        pkaddr->addr_type = KRB5_ADDRESS_INET;
        pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
@@ -170,7 +170,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context,
 }
 #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS)
 /* MIT */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
+ void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr)
 {
        pkaddr->addrtype = ADDRTYPE_INET;
        pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
index 3b5818a015745e9736203369493dd742c83f4d08..d5bf1828c6819a6dcb2e9944f5b39ff2940c72ef 100644 (file)
@@ -626,7 +626,7 @@ find_server(SMBCCTX *context,
  * Connect to a server, possibly on an existing connection
  *
  * Here, what we want to do is: If the server and username
- * match an existing connection, reuse that, otherwise, establish a 
+ * match an existing connection, reuse that, otherwise, establish a
  * new connection.
  *
  * If we have to create a new connection, call the auth_fn to get the
@@ -637,9 +637,9 @@ static SMBCSRV *
 smbc_server(SMBCCTX *context,
             bool connect_if_not_found,
             const char *server,
-            const char *share, 
+            const char *share,
             fstring workgroup,
-            fstring username, 
+            fstring username,
             fstring password)
 {
        SMBCSRV *srv=NULL;
@@ -647,14 +647,14 @@ smbc_server(SMBCCTX *context,
        struct nmb_name called, calling;
        const char *server_n = server;
        pstring ipenv;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        int tried_reverse = 0;
         int port_try_first;
         int port_try_next;
         const char *username_used;
        NTSTATUS status;
 
-       zero_ip_v4(&ip);
+       zero_addr(&ss, AF_INET);
        ZERO_STRUCT(c);
 
        if (server[0] == 0) {
@@ -665,7 +665,7 @@ smbc_server(SMBCCTX *context,
         /* Look for a cached connection */
         srv = find_server(context, server, share,
                           workgroup, username, password);
-        
+
         /*
          * If we found a connection and we're only allowed one share per
          * server...
@@ -699,7 +699,7 @@ smbc_server(SMBCCTX *context,
 
                         if (! cli_send_tconX(srv->cli, share, "?????",
                                              password, strlen(password)+1)) {
-                        
+
                                 errno = smbc_errno(context, srv->cli);
                                 cli_shutdown(srv->cli);
                                srv->cli = NULL;
@@ -718,7 +718,7 @@ smbc_server(SMBCCTX *context,
                         }
                 }
         }
-        
+
         /* If we have a connection... */
         if (srv) {
 
@@ -736,13 +736,13 @@ smbc_server(SMBCCTX *context,
        make_nmb_name(&called , server, 0x20);
 
        DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
-  
+
        DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
 
  again:
        slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
 
-       zero_ip_v4(&ip);
+       zero_addr(&ss, AF_INET);
 
        /* have to open a new connection */
        if ((c = cli_initialise()) == NULL) {
@@ -773,13 +773,13 @@ smbc_server(SMBCCTX *context,
 
         c->port = port_try_first;
 
-       status = cli_connect(c, server_n, &ip);
+       status = cli_connect(c, server_n, &ss);
        if (!NT_STATUS_IS_OK(status)) {
 
                 /* First connection attempt failed.  Try alternate port. */
                 c->port = port_try_next;
 
-                status = cli_connect(c, server_n, &ip);
+                status = cli_connect(c, server_n, &ss);
                if (!NT_STATUS_IS_OK(status)) {
                        cli_shutdown(c);
                        errno = ETIMEDOUT;
@@ -796,20 +796,22 @@ smbc_server(SMBCCTX *context,
 
                        /* Only try this if server is an IP address ... */
 
-                       if (is_ipaddress_v4(server) && !tried_reverse) {
+                       if (is_ipaddress(server) && !tried_reverse) {
                                fstring remote_name;
-                               struct in_addr rem_ip;
+                               struct sockaddr_storage rem_ss;
 
-                               if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
+                               if (!interpret_string_addr(&rem_ss, server,
+                                                       NI_NUMERICHOST)) {
                                        DEBUG(4, ("Could not convert IP address "
-                                               "%s to struct in_addr\n", server));
+                                               "%s to struct sockaddr_storage\n",
+                                               server));
                                        errno = ETIMEDOUT;
                                        return NULL;
                                }
 
                                tried_reverse++; /* Yuck */
 
-                               if (name_status_find("*", 0, 0, rem_ip, remote_name)) {
+                               if (name_status_find("*", 0, 0, &rem_ss, remote_name)) {
                                        make_nmb_name(&called, remote_name, 0x20);
                                        goto again;
                                }
@@ -818,9 +820,9 @@ smbc_server(SMBCCTX *context,
                errno = ETIMEDOUT;
                return NULL;
        }
-  
+
        DEBUG(4,(" session request ok\n"));
-  
+
        if (!cli_negprot(c)) {
                cli_shutdown(c);
                errno = ETIMEDOUT;
@@ -829,11 +831,11 @@ smbc_server(SMBCCTX *context,
 
         username_used = username;
 
-       if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, 
+       if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
                                               password, strlen(password),
                                               password, strlen(password),
                                               workgroup))) {
-                
+
                 /* Failed.  Try an anonymous login, if allowed by flags. */
                 username_used = "";
 
@@ -857,9 +859,9 @@ smbc_server(SMBCCTX *context,
                cli_shutdown(c);
                return NULL;
        }
-  
+
        DEBUG(4,(" tconx ok\n"));
-  
+
        /*
         * Ok, we have got a nice connection
         * Let's allocate a server structure.
@@ -892,8 +894,8 @@ smbc_server(SMBCCTX *context,
                }
                goto failed;
        }
-       
-       DEBUG(2, ("Server connect ok: //%s/%s: %p\n", 
+
+       DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
                  server, share, srv));
 
        DLIST_ADD(context->internal->_servers, srv);
@@ -904,7 +906,7 @@ smbc_server(SMBCCTX *context,
        if (!srv) {
                return NULL;
        }
-  
+
        SAFE_FREE(srv);
        return NULL;
 }
@@ -916,14 +918,14 @@ smbc_server(SMBCCTX *context,
 static SMBCSRV *
 smbc_attr_server(SMBCCTX *context,
                  const char *server,
-                 const char *share, 
+                 const char *share,
                  fstring workgroup,
                  fstring username,
                  fstring password,
                  POLICY_HND *pol)
 {
         int flags;
-        struct in_addr ip;
+        struct sockaddr_storage ss;
        struct cli_state *ipc_cli;
        struct rpc_pipe_client *pipe_hnd;
         NTSTATUS nt_status;
@@ -956,16 +958,16 @@ smbc_attr_server(SMBCCTX *context,
                                         password, sizeof(fstring));
                         }
                 }
-        
+
                 flags = 0;
                 if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
                         flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
                 }
 
-                zero_ip_v4(&ip);
+                zero_addr(&ss, AF_INET);
                 nt_status = cli_full_connection(&ipc_cli,
-                                                global_myname(), server, 
-                                                &ip, 0, "IPC$", "?????",  
+                                                global_myname(), server,
+                                                &ss, 0, "IPC$", "?????",
                                                 username, workgroup,
                                                 password, flags,
                                                 Undefined, NULL);
@@ -2557,7 +2559,7 @@ smbc_opendir_ctx(SMBCCTX *context,
        SMBCSRV *srv  = NULL;
        SMBCFILE *dir = NULL;
         struct _smbc_callbacks *cb;
-       struct in_addr rem_ip;
+       struct sockaddr_storage rem_ss;
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
@@ -2602,10 +2604,8 @@ smbc_opendir_ctx(SMBCCTX *context,
        dir = SMB_MALLOC_P(SMBCFILE);
 
        if (!dir) {
-
                errno = ENOMEM;
                return NULL;
-
        }
 
        ZERO_STRUCTP(dir);
@@ -2661,7 +2661,7 @@ smbc_opendir_ctx(SMBCCTX *context,
 
                         SAFE_FREE(ip_list);
 
-                        if (!find_master_ip(workgroup, &server_addr.ip)) {
+                        if (!find_master_ip(workgroup, &server_addr.ss)) {
 
                                if (dir) {
                                        SAFE_FREE(dir->fname);
@@ -2676,13 +2676,15 @@ smbc_opendir_ctx(SMBCCTX *context,
                 }
 
                 for (i = 0; i < count && i < max_lmb_count; i++) {
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
                         DEBUG(99, ("Found master browser %d of %d: %s\n",
                                    i+1, MAX(count, max_lmb_count),
-                                   inet_ntoa(ip_list[i].ip)));
-                        
+                                   addr));
+
                         cli = get_ipc_connect_master_ip(&ip_list[i],
                                                         workgroup, &u_info);
-                       /* cli == NULL is the master browser refused to talk or 
+                       /* cli == NULL is the master browser refused to talk or
                           could not be found */
                        if ( !cli )
                                continue;
@@ -2699,18 +2701,18 @@ smbc_opendir_ctx(SMBCCTX *context,
                          * already have one, and determine the
                          * workgroups/domains that it knows about.
                          */
-                
+
                         srv = smbc_server(context, True, server, "IPC$",
                                           workgroup, user, password);
                         if (!srv) {
                                 continue;
                         }
-                
+
                         dir->srv = srv;
                         dir->dir_type = SMBC_WORKGROUP;
 
                         /* Now, list the stuff ... */
-                        
+
                         if (!cli_NetServerEnum(srv->cli,
                                                workgroup,
                                                SV_TYPE_DOMAIN_ENUM,
@@ -2721,7 +2723,7 @@ smbc_opendir_ctx(SMBCCTX *context,
                 }
 
                 SAFE_FREE(ip_list);
-        } else { 
+        } else {
                 /*
                  * Server not an empty string ... Check the rest and see what
                  * gives
@@ -2761,9 +2763,9 @@ smbc_opendir_ctx(SMBCCTX *context,
                          * LMB or DMB
                          */
                        if (!srv &&
-                            !is_ipaddress_v4(server) &&
-                           (resolve_name(server, &rem_ip, 0x1d) ||   /* LMB */
-                             resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */
+                            !is_ipaddress(server) &&
+                           (resolve_name(server, &rem_ss, 0x1d) ||   /* LMB */
+                             resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
 
                                fstring buserver;
 
@@ -2773,7 +2775,7 @@ smbc_opendir_ctx(SMBCCTX *context,
                                 * Get the backup list ...
                                 */
                                if (!name_status_find(server, 0, 0,
-                                                      rem_ip, buserver)) {
+                                                      &rem_ss, buserver)) {
 
                                         DEBUG(0, ("Could not get name of "
                                                   "local/domain master browser "
@@ -2818,8 +2820,8 @@ smbc_opendir_ctx(SMBCCTX *context,
                                        return NULL;
                                }
                        } else if (srv ||
-                                   (resolve_name(server, &rem_ip, 0x20))) {
-                                
+                                   (resolve_name(server, &rem_ss, 0x20))) {
+
                                 /* If we hadn't found the server, get one now */
                                 if (!srv) {
                                         srv = smbc_server(context, True,
@@ -2848,9 +2850,9 @@ smbc_opendir_ctx(SMBCCTX *context,
                                             (void *) dir) < 0 &&
                                     cli_RNetShareEnum(
                                             srv->cli,
-                                            list_fn, 
+                                            list_fn,
                                             (void *)dir) < 0) {
-                                                
+
                                         errno = cli_errno(srv->cli);
                                         if (dir) {
                                                 SAFE_FREE(dir->fname);
@@ -2861,7 +2863,7 @@ smbc_opendir_ctx(SMBCCTX *context,
                                 }
                         } else {
                                 /* Neither the workgroup nor server exists */
-                                errno = ECONNREFUSED;   
+                                errno = ECONNREFUSED;
                                 if (dir) {
                                         SAFE_FREE(dir->fname);
                                         SAFE_FREE(dir);
index b569100d94fef3b2a235a257d912bbb610ed4336..6a675d2ef2cc8aefdd733da8efe85c1b4ebab94a 100644 (file)
@@ -1,21 +1,22 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    NetBIOS name cache module on top of gencache mechanism.
-   
+
    Copyright (C) Tim Potter         2002
    Copyright (C) Rafal Szczesniak   2002
-   
+   Copyright (C) Jeremy Allison     2007
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #define NBTKEY_FMT  "NBT/%s#%02X"
 
-
 /**
  * Initialise namecache system. Function calls gencache
  * initialisation function to perform necessary actions
- * 
+ *
  * @return true upon successful initialisation of the cache or
  *         false on failure
  **/
@@ -38,7 +38,7 @@ bool namecache_enable(void)
        /*
         * Check if name caching disabled by setting the name cache
         * timeout to zero.
-        */ 
+        */
 
        if (lp_name_cache_timeout() == 0) {
                DEBUG(5, ("namecache_enable: disabling netbios name cache\n"));
@@ -48,18 +48,19 @@ bool namecache_enable(void)
        /* Init namecache by calling gencache initialisation */
 
        if (!gencache_init()) {
-               DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n"));
+               DEBUG(2, ("namecache_enable: "
+                       "Couldn't initialise namecache on top of gencache.\n"));
                return False;
        }
 
-       /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */
+       /* I leave it for now, though I don't think we really
+        * need this (mimir, 27.09.2002) */
        DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
                  "seconds\n", lp_name_cache_timeout()));
 
        return True;
 }
 
-
 /**
  * Shutdown namecache. Routine calls gencache close function
  * to safely close gencache file.
@@ -67,19 +68,20 @@ bool namecache_enable(void)
  * @return true upon successful shutdown of the cache or
  *         false on failure
  **/
+
 bool namecache_shutdown(void)
 {
        if (!gencache_shutdown()) {
-               DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n"));
+               DEBUG(2, ("namecache_shutdown: "
+                       "Couldn't close namecache on top of gencache.\n"));
                return False;
        }
-       
-       DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n"));
+
+       DEBUG(5, ("namecache_shutdown: "
+               "netbios namecache closed successfully.\n"));
        return True;
 }
 
-
 /**
  * Generates a key for netbios name lookups on basis of
  * netbios name and type.
@@ -92,7 +94,8 @@ bool namecache_shutdown(void)
  *         type number
  */
 
-static char* namecache_key(const char *name, int name_type)
+static char* namecache_key(const char *name,
+                               int name_type)
 {
        char *keystr;
        asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type);
@@ -100,7 +103,6 @@ static char* namecache_key(const char *name, int name_type)
        return keystr;
 }
 
-
 /**
  * Store a name(s) in the name cache
  *
@@ -111,8 +113,10 @@ static char* namecache_key(const char *name, int name_type)
  *        ip addresses being stored
  **/
 
-bool namecache_store(const char *name, int name_type,
-                     int num_names, struct ip_service *ip_list)
+bool namecache_store(const char *name,
+                       int name_type,
+                       int num_names,
+                       struct ip_service *ip_list)
 {
        time_t expiry;
        char *key, *value_string;
@@ -123,23 +127,35 @@ bool namecache_store(const char *name, int name_type,
         * we use gecache call to avoid annoying debug messages about
         * initialised namecache again and again...
         */
-       if (!gencache_init()) return False;
+       if (!gencache_init()) {
+               return False;
+       }
 
        if (name_type > 255) {
                return False; /* Don't store non-real name types. */
        }
 
        if ( DEBUGLEVEL >= 5 ) {
+               TALLOC_CTX *ctx = talloc_stackframe();
+               char *addr = NULL;
+
                DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
                        num_names, num_names == 1 ? "": "es", name, name_type));
 
-               for (i = 0; i < num_names; i++) 
-                       DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip), 
-                               ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
-                       
+               for (i = 0; i < num_names; i++) {
+                       addr = print_canonical_sockaddr(ctx,
+                                                       &ip_list[i].ss);
+                       if (!addr) {
+                               continue;
+                       }
+                       DEBUGADD(5, ("%s%s", addr,
+                               (i == (num_names - 1) ? "" : ",")));
+
+               }
                DEBUGADD(5, ("\n"));
+               TALLOC_FREE(ctx);
        }
-       
+
        key = namecache_key(name, name_type);
        if (!key) {
                return False;
@@ -155,9 +171,9 @@ bool namecache_store(const char *name, int name_type,
        if (!ipstr_list_make(&value_string, ip_list, num_names)) {
                SAFE_FREE(key);
                SAFE_FREE(value_string);
-               return False;
+               return false;
        }
-       
+
        /* set the entry */
        ret = gencache_set(key, value_string, expiry);
        SAFE_FREE(key);
@@ -165,7 +181,6 @@ bool namecache_store(const char *name, int name_type,
        return ret;
 }
 
-
 /**
  * Look up a name in the cache.
  *
@@ -179,17 +194,22 @@ bool namecache_store(const char *name, int name_type,
  *         false if name isn't found in the cache or has expired
  **/
 
-bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_list,
-                     int *num_names)
+bool namecache_fetch(const char *name,
+                       int name_type,
+                       struct ip_service **ip_list,
+                       int *num_names)
 {
        char *key, *value;
        time_t timeout;
 
        /* exit now if null pointers were passed as they're required further */
-       if (!ip_list || !num_names) return False;
+       if (!ip_list || !num_names) {
+               return False;
+       }
 
-       if (!gencache_init())
+       if (!gencache_init()) {
                return False;
+       }
 
        if (name_type > 255) {
                return False; /* Don't fetch non-real name types. */
@@ -197,7 +217,7 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis
 
        *num_names = 0;
 
-       /* 
+       /*
         * Use gencache interface - lookup the key
         */
        key = namecache_key(name, name_type);
@@ -212,16 +232,16 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis
        } else {
                DEBUG(5, ("name %s#%02X found.\n", name, name_type));
        }
-       
+
        /*
         * Split up the stored value into the list of IP adresses
         */
        *num_names = ipstr_list_parse(value, ip_list);
-       
+
        SAFE_FREE(key);
        SAFE_FREE(value);
-                        
-       return *num_names > 0;          /* true only if some ip has been fetched */
+
+       return *num_names > 0; /* true only if some ip has been fetched */
 }
 
 /**
@@ -256,27 +276,30 @@ bool namecache_delete(const char *name, int name_type)
  *
  **/
 
-static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr)
+static void flush_netbios_name(const char *key,
+                       const char *value,
+                       time_t timeout,
+                       void *dptr)
 {
        gencache_del(key);
        DEBUG(5, ("Deleting entry %s\n", key));
 }
 
-
 /**
  * Flush all names from the name cache.
  * It's done by gencache_iterate()
  *
- * @return True upon successful deletion or
- *         False in case of an error
+ * @return true upon successful deletion or
+ *         false in case of an error
  **/
 
 void namecache_flush(void)
 {
-       if (!gencache_init())
+       if (!gencache_init()) {
                return;
+       }
 
-       /* 
+       /*
         * iterate through each NBT cache's entry and flush it
         * by flush_netbios_name function
         */
@@ -286,40 +309,49 @@ void namecache_flush(void)
 
 /* Construct a name status record key. */
 
-static char *namecache_status_record_key(const char *name, int name_type1,
-                               int name_type2, struct in_addr keyip)
+static char *namecache_status_record_key(const char *name,
+                               int name_type1,
+                               int name_type2,
+                               const struct sockaddr_storage *keyip)
 {
+       char addr[INET6_ADDRSTRLEN];
        char *keystr;
 
+       print_sockaddr(addr, sizeof(addr), keyip);
        asprintf(&keystr, "NBT/%s#%02X.%02X.%s",
-                       strupper_static(name), name_type1, name_type2, inet_ntoa(keyip));
+                       strupper_static(name), name_type1, name_type2, addr);
        return keystr;
 }
 
 /* Store a name status record. */
 
 bool namecache_status_store(const char *keyname, int keyname_type,
-               int name_type, struct in_addr keyip,
+               int name_type, const struct sockaddr_storage *keyip,
                const char *srvname)
 {
        char *key;
        time_t expiry;
        bool ret;
 
-       if (!gencache_init())
+       if (!gencache_init()) {
                return False;
+       }
 
-       key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+       key = namecache_status_record_key(keyname, keyname_type,
+                       name_type, keyip);
        if (!key)
                return False;
 
        expiry = time(NULL) + lp_name_cache_timeout();
        ret = gencache_set(key, srvname, expiry);
 
-       if (ret)
-               DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname ));
-       else
-               DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key ));
+       if (ret) {
+               DEBUG(5, ("namecache_status_store: entry %s -> %s\n",
+                                       key, srvname ));
+       } else {
+               DEBUG(5, ("namecache_status_store: entry %s store failed.\n",
+                                       key ));
+       }
 
        SAFE_FREE(key);
        return ret;
@@ -327,8 +359,11 @@ bool namecache_status_store(const char *keyname, int keyname_type,
 
 /* Fetch a name status record. */
 
-bool namecache_status_fetch(const char *keyname, int keyname_type,
-                       int name_type, struct in_addr keyip, char *srvname_out)
+bool namecache_status_fetch(const char *keyname,
+                               int keyname_type,
+                               int name_type,
+                               const struct sockaddr_storage *keyip,
+                               char *srvname_out)
 {
        char *key = NULL;
        char *value = NULL;
@@ -337,16 +372,19 @@ bool namecache_status_fetch(const char *keyname, int keyname_type,
        if (!gencache_init())
                return False;
 
-       key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+       key = namecache_status_record_key(keyname, keyname_type,
+                       name_type, keyip);
        if (!key)
                return False;
 
        if (!gencache_get(key, &value, &timeout)) {
-               DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key));
+               DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n",
+                                       key));
                SAFE_FREE(key);
                return False;
        } else {
-               DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value ));
+               DEBUG(5, ("namecache_status_fetch: key %s -> %s\n",
+                                       key, value ));
        }
 
        strlcpy(srvname_out, value, 16);
index 6585fd751c096d563fe206902c3e3f7ca268f18e..34fe09b8c2988e475d4af827daefb09b1656de83 100644 (file)
@@ -1,20 +1,21 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    name query routines
    Copyright (C) Andrew Tridgell 1994-1998
-   
+   Copyright (C) Jeremy Allison 2007.
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.   
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -25,10 +26,10 @@ bool global_in_nmbd = False;
 /****************************
  * SERVER AFFINITY ROUTINES *
  ****************************/
- /* Server affinity is the concept of preferring the last domain 
+
+ /* Server affinity is the concept of preferring the last domain
     controller with whom you had a successful conversation */
+
 /****************************************************************************
 ****************************************************************************/
 #define SAFKEY_FMT     "SAF/DOMAIN/%s"
@@ -37,7 +38,7 @@ bool global_in_nmbd = False;
 static char *saf_key(const char *domain)
 {
        char *keystr;
-       
+
        asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
 
        return keystr;
@@ -51,31 +52,32 @@ bool saf_store( const char *domain, const char *servername )
        char *key;
        time_t expire;
        bool ret = False;
-       
+
        if ( !domain || !servername ) {
-               DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
+               DEBUG(2,("saf_store: "
+                       "Refusing to store empty domain or servername!\n"));
                return False;
        }
 
        if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
-               DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
+               DEBUG(0,("saf_store: "
+                       "refusing to store 0 length domain or servername!\n"));
                return False;
        }
-       
-       if ( !gencache_init() ) 
+
+       if ( !gencache_init() )
                return False;
-       
+
        key = saf_key( domain );
        expire = time( NULL ) + SAF_TTL;
-       
-       
+
        DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
                domain, servername, (unsigned int)expire ));
-               
+
        ret = gencache_set( key, servername, expire );
-       
+
        SAFE_FREE( key );
-       
+
        return ret;
 }
 
@@ -83,20 +85,20 @@ bool saf_delete( const char *domain )
 {
        char *key;
        bool ret = False;
-       
+
        if ( !domain ) {
-               DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));             
+               DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
                return False;
        }
-       
-       if ( !gencache_init() ) 
+
+       if ( !gencache_init() )
                return False;
-       
+
        key = saf_key(domain);
        ret = gencache_del(key);
-       
+
        if (ret) {
-               DEBUG(10,("saf_delete: domain = [%s]\n", domain ));             
+               DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
        }
 
        SAFE_FREE( key );
@@ -118,23 +120,24 @@ char *saf_fetch( const char *domain )
                DEBUG(2,("saf_fetch: Empty domain name!\n"));
                return NULL;
        }
-       
-       if ( !gencache_init() ) 
+
+       if ( !gencache_init() )
                return False;
-       
+
        key = saf_key( domain );
-       
+
        ret = gencache_get( key, &server, &timeout );
-       
+
        SAFE_FREE( key );
-       
+
        if ( !ret ) {
-               DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
+               DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
+                                       domain ));
        } else {
-               DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", 
+               DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
                        server, domain ));
        }
-               
+
        return server;
 }
 
@@ -155,7 +158,9 @@ static int generate_trn_id(void)
  Parse a node status response into an array of structures.
 ****************************************************************************/
 
-static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
+static NODE_STATUS_STRUCT *parse_node_status(char *p,
+                               int *num_names,
+                               struct node_status_extra *extra)
 {
        NODE_STATUS_STRUCT *ret;
        int i;
@@ -176,7 +181,7 @@ static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct nod
                ret[i].type = CVAL(p,15);
                ret[i].flags = p[16];
                p += 18;
-               DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
+               DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
                           ret[i].type, ret[i].flags));
        }
        /*
@@ -194,9 +199,11 @@ static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct nod
  structures holding the returned names or NULL if the query failed.
 **************************************************************************/
 
-NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
-                                     struct in_addr to_ip, int *num_names,
-                                     struct node_status_extra *extra)
+NODE_STATUS_STRUCT *node_status_query(int fd,
+                                       struct nmb_name *name,
+                                       const struct sockaddr_storage *to_ss,
+                                       int *num_names,
+                                       struct node_status_extra *extra)
 {
        bool found=False;
        int retries = 2;
@@ -209,14 +216,18 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
 
        ZERO_STRUCT(p);
 
+       if (to_ss->ss_family != AF_INET) {
+               /* Can't do node status to IPv6 */
+               return NULL;
+       }
        nmb->header.name_trn_id = generate_trn_id();
        nmb->header.opcode = 0;
-       nmb->header.response = False;
-       nmb->header.nm_flags.bcast = False;
-       nmb->header.nm_flags.recursion_available = False;
-       nmb->header.nm_flags.recursion_desired = False;
-       nmb->header.nm_flags.trunc = False;
-       nmb->header.nm_flags.authoritative = False;
+       nmb->header.response = false;
+       nmb->header.nm_flags.bcast = false;
+       nmb->header.nm_flags.recursion_available = false;
+       nmb->header.nm_flags.recursion_desired = false;
+       nmb->header.nm_flags.trunc = false;
+       nmb->header.nm_flags.authoritative = false;
        nmb->header.rcode = 0;
        nmb->header.qdcount = 1;
        nmb->header.ancount = 0;
@@ -226,15 +237,15 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
        nmb->question.question_type = 0x21;
        nmb->question.question_class = 0x1;
 
-       p.ip = to_ip;
+       p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
        p.port = NMB_PORT;
        p.fd = fd;
        p.timestamp = time(NULL);
        p.packet_type = NMB_PACKET;
-       
+
        GetTimeOfDay(&tval);
-  
-       if (!send_packet(&p)) 
+
+       if (!send_packet(&p))
                return NULL;
 
        retries--;
@@ -251,10 +262,10 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
                        retries--;
                }
 
-               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
+               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
                        struct nmb_packet *nmb2 = &p2->packet.nmb;
                        debug_nmb_packet(p2);
-                       
+
                        if (nmb2->header.opcode != 0 ||
                            nmb2->header.nm_flags.bcast ||
                            nmb2->header.rcode ||
@@ -267,12 +278,13 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
                                continue;
                        }
 
-                       ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
+                       ret = parse_node_status(&nmb2->answers->rdata[0],
+                                       num_names, extra);
                        free_packet(p2);
                        return ret;
                }
        }
-       
+
        return NULL;
 }
 
@@ -281,34 +293,54 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
  a servers name given its IP. Return the matched name in *name.
 **************************************************************************/
 
-bool name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
+bool name_status_find(const char *q_name,
+                       int q_type,
+                       int type,
+                       const struct sockaddr_storage *to_ss,
+                       fstring name)
 {
+       char addr[INET6_ADDRSTRLEN];
+       struct sockaddr_storage ss;
        NODE_STATUS_STRUCT *status = NULL;
        struct nmb_name nname;
        int count, i;
        int sock;
-       bool result = False;
+       bool result = false;
 
        if (lp_disable_netbios()) {
-               DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
+               DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
+                                       q_name, q_type));
                return False;
        }
 
-       DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
-                  q_type, inet_ntoa(to_ip)));
+       print_sockaddr(addr, sizeof(addr), to_ss);
+
+       DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
+                  q_type, addr));
 
        /* Check the cache first. */
 
-       if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
+       if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
                return True;
+       }
+
+       if (to_ss->ss_family != AF_INET) {
+               /* Can't do node status to IPv6 */
+               return false;
+       }
+
+       if (!interpret_string_addr(&ss, lp_socket_address(),
+                               AI_NUMERICHOST|AI_PASSIVE)) {
+               zero_addr(&ss, AF_INET);
+       }
 
-       sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
+       sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
        if (sock == -1)
                goto done;
 
        /* W2K PDC's seem not to respond to '*'#0. JRA */
        make_nmb_name(&nname, q_name, q_type);
-       status = node_status_query(sock, &nname, to_ip, &count, NULL);
+       status = node_status_query(sock, &nname, to_ss, &count, NULL);
        close(sock);
        if (!status)
                goto done;
@@ -323,13 +355,14 @@ bool name_status_find(const char *q_name, int q_type, int type, struct in_addr t
        pull_ascii_nstring(name, sizeof(fstring), status[i].name);
 
        /* Store the result in the cache. */
-       /* but don't store an entry for 0x1c names here.  Here we have 
+       /* but don't store an entry for 0x1c names here.  Here we have
           a single host and DOMAIN<0x1c> names should be a list of hosts */
-          
-       if ( q_type != 0x1c )
-               namecache_status_store(q_name, q_type, type, to_ip, name);
 
-       result = True;
+       if ( q_type != 0x1c ) {
+               namecache_status_store(q_name, q_type, type, to_ss, name);
+       }
+
+       result = true;
 
  done:
        SAFE_FREE(status);
@@ -337,49 +370,92 @@ bool name_status_find(const char *q_name, int q_type, int type, struct in_addr t
        DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
 
        if (result)
-               DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
+               DEBUGADD(10, (", name %s ip address is %s", name, addr));
 
-       DEBUG(10, ("\n"));      
+       DEBUG(10, ("\n"));
 
        return result;
 }
 
 /*
-  comparison function used by sort_ip_list
+  comparison function used by sort_addr_list
 */
 
-static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+static int addr_compare(const struct sockaddr_storage *ss1,
+               const struct sockaddr_storage *ss2)
 {
        int max_bits1=0, max_bits2=0;
        int num_interfaces = iface_count();
-       struct sockaddr_storage ss;
        int i;
 
+       /* Sort IPv6 addresses first. */
+       if (ss1->ss_family != ss2->ss_family) {
+               if (ss2->ss_family == AF_INET) {
+                       return -1;
+               } else {
+                       return 1;
+               }
+       }
+
+       /* Here we know both addresses are of the same
+        * family. */
+
        for (i=0;i<num_interfaces;i++) {
                const struct sockaddr_storage *pss = iface_n_bcast(i);
-               struct in_addr ip;
+               unsigned char *p_ss1 = NULL;
+               unsigned char *p_ss2 = NULL;
+               unsigned char *p_if = NULL;
+               size_t len = 0;
                int bits1, bits2;
 
-               if (pss->ss_family != AF_INET) {
+               if (pss->ss_family != ss1->ss_family) {
+                       /* Ignore interfaces of the wrong type. */
                        continue;
                }
-               ip = ((const struct sockaddr_in *)pss)->sin_addr;
-               bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
-               bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
+               if (pss->ss_family == AF_INET) {
+                       p_if = (unsigned char *)
+                               &((const struct sockaddr_in *)pss)->sin_addr;
+                       p_ss1 = (unsigned char *)
+                               &((const struct sockaddr_in *)ss1)->sin_addr;
+                       p_ss2 = (unsigned char *)
+                               &((const struct sockaddr_in *)ss2)->sin_addr;
+                       len = 4;
+               }
+#if defined(HAVE_IPV6)
+               if (pss->ss_family == AF_INET6) {
+                       p_if = (unsigned char *)
+                               &((const struct sockaddr_in6 *)pss)->sin6_addr;
+                       p_ss1 = (unsigned char *)
+                               &((const struct sockaddr_in6 *)ss1)->sin6_addr;
+                       p_ss2 = (unsigned char *)
+                               &((const struct sockaddr_in6 *)ss2)->sin6_addr;
+                       len = 16;
+               }
+#endif
+               if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
+                       continue;
+               }
+               bits1 = matching_len_bits(p_ss1, p_if, len);
+               bits2 = matching_len_bits(p_ss2, p_if, len);
                max_bits1 = MAX(bits1, max_bits1);
                max_bits2 = MAX(bits2, max_bits2);
-       }       
-       
-       /* bias towards directly reachable IPs */
-       in_addr_to_sockaddr_storage(&ss, *ip1);
-       if (iface_local(&ss)) {
-               max_bits1 += 32;
-       }
-       in_addr_to_sockaddr_storage(&ss, *ip1);
-       if (iface_local(&ss)) {
-               max_bits2 += 32;
        }
 
+       /* Bias towards directly reachable IPs */
+       if (iface_local(ss1)) {
+               if (ss1->ss_family == AF_INET) {
+                       max_bits1 += 32;
+               } else {
+                       max_bits1 += 128;
+               }
+       }
+       if (iface_local(ss2)) {
+               if (ss2->ss_family == AF_INET) {
+                       max_bits2 += 32;
+               } else {
+                       max_bits2 += 128;
+               }
+       }
        return max_bits2 - max_bits1;
 }
 
@@ -387,73 +463,84 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
  compare 2 ldap IPs by nearness to our interfaces - used in qsort
 *******************************************************************/
 
-int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
+int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
 {
        int result;
-       
-       if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
+
+       if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
                return result;
-               
-       if ( ip1->port > ip2->port )
+       }
+
+       if (ss1->port > ss2->port) {
                return 1;
-       
-       if ( ip1->port < ip2->port )
+       }
+
+       if (ss1->port < ss2->port) {
                return -1;
-               
+       }
+
        return 0;
 }
 
 /*
-  sort an IP list so that names that are close to one of our interfaces 
-  are at the top. This prevents the problem where a WINS server returns an IP that
-  is not reachable from our subnet as the first match
+  sort an IP list so that names that are close to one of our interfaces
+  are at the top. This prevents the problem where a WINS server returns an IP
+  that is not reachable from our subnet as the first match
 */
 
-static void sort_ip_list(struct in_addr *iplist, int count)
+static void sort_addr_list(struct sockaddr_storage *sslist, int count)
 {
        if (count <= 1) {
                return;
        }
 
-       qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
+       qsort(sslist, count, sizeof(struct sockaddr_storage),
+                       QSORT_CAST addr_compare);
 }
 
-static void sort_ip_list2(struct ip_service *iplist, int count)
+static void sort_service_list(struct ip_service *servlist, int count)
 {
        if (count <= 1) {
                return;
        }
 
-       qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); 
+       qsort(servlist, count, sizeof(struct ip_service),
+                       QSORT_CAST ip_service_compare);
 }
 
 /**********************************************************************
- Remove any duplicate address/port pairs in the list 
+ Remove any duplicate address/port pairs in the list
  *********************************************************************/
 
-static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
+static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
 {
        int i, j;
-       
-       DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
-       
+
+       DEBUG(10,("remove_duplicate_addrs2: "
+                       "looking for duplicate address/port pairs\n"));
+
        /* one loop to remove duplicates */
        for ( i=0; i<count; i++ ) {
-               if ( is_zero_ip_v4(iplist[i].ip) )
+               if ( is_zero_addr(&iplist[i].ss)) {
                        continue;
-                                       
+               }
+
                for ( j=i+1; j<count; j++ ) {
-                       if ( ip_service_equal(iplist[i], iplist[j]) )
-                               zero_ip_v4(&iplist[j].ip);
+                       if (addr_equal(&iplist[i].ss, &iplist[j].ss) &&
+                                       iplist[i].port == iplist[j].port) {
+                               zero_addr(&iplist[j].ss, AF_INET);
+                       }
                }
        }
-                       
+
        /* one loop to clean up any holes we left */
        /* first ip should never be a zero_ip() */
        for (i = 0; i<count; ) {
-               if ( is_zero_ip_v4(iplist[i].ip) ) {
-                       if (i != count-1 )
-                               memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
+               if (is_zero_addr(&iplist[i].ss) ) {
+                       if (i != count-1) {
+                               memmove(&iplist[i], &iplist[i+1],
+                                       (count - i - 1)*sizeof(iplist[i]));
+                       }
                        count--;
                        continue;
                }
@@ -470,68 +557,78 @@ static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
  *timed_out is set if we failed by timing out
 ****************************************************************************/
 
-struct in_addr *name_query(int fd,const char *name,int name_type, 
-                          bool bcast,bool recurse,
-                          struct in_addr to_ip, int *count, int *flags,
-                          bool *timed_out)
+struct sockaddr_storage *name_query(int fd,
+                       const char *name,
+                       int name_type,
+                       bool bcast,
+                       bool recurse,
+                       const struct sockaddr_storage *to_ss,
+                       int *count,
+                       int *flags,
+                       bool *timed_out)
 {
-       bool found=False;
+       bool found=false;
        int i, retries = 3;
        int retry_time = bcast?250:2000;
        struct timeval tval;
        struct packet_struct p;
        struct packet_struct *p2;
        struct nmb_packet *nmb = &p.packet.nmb;
-       struct in_addr *ip_list = NULL;
+       struct sockaddr_storage *ss_list = NULL;
 
        if (lp_disable_netbios()) {
-               DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
+               DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
+                                       name, name_type));
+               return NULL;
+       }
+
+       if (to_ss->ss_family != AF_INET) {
                return NULL;
        }
 
        if (timed_out) {
-               *timed_out = False;
+               *timed_out = false;
        }
-       
+
        memset((char *)&p,'\0',sizeof(p));
        (*count) = 0;
        (*flags) = 0;
-       
+
        nmb->header.name_trn_id = generate_trn_id();
        nmb->header.opcode = 0;
-       nmb->header.response = False;
+       nmb->header.response = false;
        nmb->header.nm_flags.bcast = bcast;
-       nmb->header.nm_flags.recursion_available = False;
+       nmb->header.nm_flags.recursion_available = false;
        nmb->header.nm_flags.recursion_desired = recurse;
-       nmb->header.nm_flags.trunc = False;
-       nmb->header.nm_flags.authoritative = False;
+       nmb->header.nm_flags.trunc = false;
+       nmb->header.nm_flags.authoritative = false;
        nmb->header.rcode = 0;
        nmb->header.qdcount = 1;
        nmb->header.ancount = 0;
        nmb->header.nscount = 0;
        nmb->header.arcount = 0;
-       
+
        make_nmb_name(&nmb->question.question_name,name,name_type);
-       
+
        nmb->question.question_type = 0x20;
        nmb->question.question_class = 0x1;
-       
-       p.ip = to_ip;
+
+       p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
        p.port = NMB_PORT;
        p.fd = fd;
        p.timestamp = time(NULL);
        p.packet_type = NMB_PACKET;
-       
+
        GetTimeOfDay(&tval);
-       
-       if (!send_packet(&p)) 
+
+       if (!send_packet(&p))
                return NULL;
-       
+
        retries--;
-       
+
        while (1) {
                struct timeval tval2;
-               
+
                GetTimeOfDay(&tval2);
                if (TvalDiff(&tval,&tval2) > retry_time) {
                        if (!retries)
@@ -541,52 +638,60 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
                        GetTimeOfDay(&tval);
                        retries--;
                }
-               
-               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
+
+               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
                        struct nmb_packet *nmb2 = &p2->packet.nmb;
                        debug_nmb_packet(p2);
-                       
+
                        /* If we get a Negative Name Query Response from a WINS
                         * server, we should report it and give up.
                         */
-                       if( 0 == nmb2->header.opcode            /* A query response   */
+                       if( 0 == nmb2->header.opcode    /* A query response   */
                            && !(bcast)                 /* from a WINS server */
-                           && nmb2->header.rcode               /* Error returned     */
+                           && nmb2->header.rcode       /* Error returned     */
                                ) {
-                               
+
                                if( DEBUGLVL( 3 ) ) {
                                        /* Only executed if DEBUGLEVEL >= 3 */
-                                       dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
+                                       dbgtext( "Negative name query "
+                                               "response, rcode 0x%02x: ",
+                                               nmb2->header.rcode );
                                        switch( nmb2->header.rcode ) {
                                        case 0x01:
-                                               dbgtext( "Request was invalidly formatted.\n" );
+                                               dbgtext( "Request "
+                                               "was invalidly formatted.\n" );
                                                break;
                                        case 0x02:
-                                               dbgtext( "Problem with NBNS, cannot process name.\n");
+                                               dbgtext( "Problem with NBNS, "
+                                               "cannot process name.\n");
                                                break;
                                        case 0x03:
-                                               dbgtext( "The name requested does not exist.\n" );
+                                               dbgtext( "The name requested "
+                                               "does not exist.\n" );
                                                break;
                                        case 0x04:
-                                               dbgtext( "Unsupported request error.\n" );
+                                               dbgtext( "Unsupported request "
+                                               "error.\n" );
                                                break;
                                        case 0x05:
-                                               dbgtext( "Query refused error.\n" );
+                                               dbgtext( "Query refused "
+                                               "error.\n" );
                                                break;
                                        default:
-                                               dbgtext( "Unrecognized error code.\n" );
+                                               dbgtext( "Unrecognized error "
+                                               "code.\n" );
                                                break;
                                        }
                                }
                                free_packet(p2);
                                return( NULL );
                        }
-                       
+
                        if (nmb2->header.opcode != 0 ||
                            nmb2->header.nm_flags.bcast ||
                            nmb2->header.rcode ||
                            !nmb2->header.ancount) {
-                               /* 
+                               /*
                                 * XXXX what do we do with this? Could be a
                                 * redirect, but we'll discard it for the
                                 * moment.
@@ -594,25 +699,33 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
                                free_packet(p2);
                                continue;
                        }
-                       
-                       ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
-                                               (*count) + nmb2->answers->rdlength/6 );
-                       
-                       if (!ip_list) {
+
+                       ss_list = SMB_REALLOC_ARRAY(ss_list,
+                                               struct sockaddr_storage,
+                                               (*count) +
+                                               nmb2->answers->rdlength/6);
+
+                       if (!ss_list) {
                                DEBUG(0,("name_query: Realloc failed.\n"));
                                free_packet(p2);
-                               return( NULL );
+                               return NULL;
                        }
-                       
-                       DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
+
+                       DEBUG(2,("Got a positive name query response "
+                                       "from %s ( ",
+                                       inet_ntoa(p2->ip)));
+
                        for (i=0;i<nmb2->answers->rdlength/6;i++) {
-                               putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
-                               DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
+                               struct in_addr ip;
+                               putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
+                               in_addr_to_sockaddr_storage(&ss_list[(*count)],
+                                               ip);
+                               DEBUGADD(2,("%s ",inet_ntoa(ip)));
                                (*count)++;
                        }
                        DEBUGADD(2,(")\n"));
-                       
-                       found=True;
+
+                       found=true;
                        retries=0;
                        /* We add the flags back ... */
                        if (nmb2->header.response)
@@ -639,15 +752,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
        }
 
        /* only set timed_out if we didn't fund what we where looking for*/
-       
+
        if ( !found && timed_out ) {
-               *timed_out = True;
+               *timed_out = true;
        }
 
        /* sort the ip list so we choose close servers first if possible */
-       sort_ip_list(ip_list, *count);
+       sort_addr_list(ss_list, *count);
 
-       return ip_list;
+       return ss_list;
 }
 
 /********************************************************
@@ -658,8 +771,9 @@ XFILE *startlmhosts(const char *fname)
 {
        XFILE *fp = x_fopen(fname,O_RDONLY, 0);
        if (!fp) {
-               DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
-                        fname, strerror(errno)));
+               DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
+                       "Error was %s\n",
+                       fname, strerror(errno)));
                return NULL;
        }
        return fp;
@@ -669,7 +783,8 @@ XFILE *startlmhosts(const char *fname)
  Parse the next line in the lmhosts file.
 *********************************************************/
 
-bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
+bool getlmhostsent(XFILE *fp, pstring name, int *name_type,
+               struct sockaddr_storage *pss)
 {
        pstring line;
 
@@ -708,43 +823,51 @@ bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa
                        continue;
 
                if (count > 0 && count < 2) {
-                       DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
+                       DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
+                                               line));
                        continue;
                }
 
                if (count >= 4) {
-                       DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
+                       DEBUG(0,("getlmhostsent: too many columns "
+                               "in lmhosts file (obsolete syntax)\n"));
                        continue;
                }
 
-               DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
+               DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
+                                       ip, name, flags));
 
                if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
-                       DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
+                       DEBUG(0,("getlmhostsent: group flag "
+                               "in lmhosts ignored (obsolete)\n"));
                        continue;
                }
 
-               *ipaddr = *interpret_addr2(ip);
+               if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
+                       DEBUG(0,("getlmhostsent: invalid address "
+                               "%s.\n", ip));
+               }
 
-               /* Extra feature. If the name ends in '#XX', where XX is a hex number,
-                       then only add that name type. */
+               /* Extra feature. If the name ends in '#XX',
+                * where XX is a hex number, then only add that name type. */
                if((ptr1 = strchr_m(name, '#')) != NULL) {
                        char *endptr;
                        ptr1++;
 
                        *name_type = (int)strtol(ptr1, &endptr, 16);
                        if(!*ptr1 || (endptr == ptr1)) {
-                               DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
+                               DEBUG(0,("getlmhostsent: invalid name "
+                                       "%s containing '#'.\n", name));
                                continue;
                        }
 
                        *(--ptr1) = '\0'; /* Truncate at the '#' */
                }
 
-               return True;
+               return true;
        }
 
-       return False;
+       return false;
 }
 
 /********************************************************
@@ -757,61 +880,75 @@ void endlmhosts(XFILE *fp)
 }
 
 /********************************************************
- convert an array if struct in_addrs to struct ip_service
- return False on failure.  Port is set to PORT_NONE;
+ convert an array if struct sockaddr_storage to struct ip_service
+ return false on failure.  Port is set to PORT_NONE;
 *********************************************************/
 
-static bool convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
+static bool convert_ss2service(struct ip_service **return_iplist,
+               const struct sockaddr_storage *ss_list,
+               int count)
 {
        int i;
 
-       if ( count==0 || !ip_list )
+       if ( count==0 || !ss_list )
                return False;
-               
+
        /* copy the ip address; port will be PORT_NONE */
-       if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
-               DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
+       if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
+                       NULL) {
+               DEBUG(0,("convert_ip2service: malloc failed "
+                       "for %d enetries!\n", count ));
                return False;
        }
-       
+
        for ( i=0; i<count; i++ ) {
-               (*return_iplist)[i].ip   = ip_list[i];
+               (*return_iplist)[i].ss   = ss_list[i];
                (*return_iplist)[i].port = PORT_NONE;
        }
 
-       return True;
-}      
+       return true;
+}
+
 /********************************************************
  Resolve via "bcast" method.
 *********************************************************/
 
-NTSTATUS name_resolve_bcast(const char *name, int name_type,
-                           struct ip_service **return_iplist,
-                           int *return_count)
+NTSTATUS name_resolve_bcast(const char *name,
+                       int name_type,
+                       struct ip_service **return_iplist,
+                       int *return_count)
 {
        int sock, i;
        int num_interfaces = iface_count();
-       struct in_addr *ip_list;
+       struct sockaddr_storage *ss_list;
+       struct sockaddr_storage ss;
        NTSTATUS status;
 
        if (lp_disable_netbios()) {
-               DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
+               DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
+                                       name, name_type));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
        *return_iplist = NULL;
        *return_count = 0;
-       
+
        /*
         * "bcast" means do a broadcast lookup on all the local interfaces.
         */
 
-       DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
+       DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
+               "for name %s<0x%x>\n", name, name_type));
 
-       sock = open_socket_in( SOCK_DGRAM, 0, 3,
-                              interpret_addr(lp_socket_address()), True );
+       if (!interpret_string_addr(&ss, lp_socket_address(),
+                               AI_NUMERICHOST|AI_PASSIVE)) {
+               zero_addr(&ss, AF_INET);
+       }
 
-       if (sock == -1) return NT_STATUS_UNSUCCESSFUL;
+       sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
+       if (sock == -1) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
        set_socket_options(sock,"SO_BROADCAST");
        /*
@@ -819,32 +956,32 @@ NTSTATUS name_resolve_bcast(const char *name, int name_type,
         * the first successful match.
         */
        for( i = num_interfaces-1; i >= 0; i--) {
-               struct in_addr sendto_ip;
-               const struct sockaddr_storage *ss = iface_n_bcast(i);
+               const struct sockaddr_storage *pss = iface_n_bcast(i);
                int flags;
 
                /* Done this way to fix compiler error on IRIX 5.x */
-               if (!ss || ss->ss_family != AF_INET) {
+               if (!pss) {
                        continue;
                }
-               sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr;
-               ip_list = name_query(sock, name, name_type, True, 
-                                   True, sendto_ip, return_count, &flags, NULL);
-               if( ip_list ) 
+               ss_list = name_query(sock, name, name_type, true,
+                                   true, pss, return_count, &flags, NULL);
+               if (ss_list) {
                        goto success;
+               }
        }
-       
+
        /* failed - no response */
-       
+
        close(sock);
        return NT_STATUS_UNSUCCESSFUL;
-       
+
 success:
+
        status = NT_STATUS_OK;
-       if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
+       if (!convert_ss2service(return_iplist, ss_list, *return_count) )
                status = NT_STATUS_INVALID_PARAMETER;
-       
-       SAFE_FREE( ip_list );
+
+       SAFE_FREE(ss_list);
        close(sock);
        return status;
 }
@@ -853,27 +990,32 @@ success:
  Resolve via "wins" method.
 *********************************************************/
 
-NTSTATUS resolve_wins(const char *name, int name_type,
-                     struct ip_service **return_iplist,
-                     int *return_count)
+NTSTATUS resolve_wins(const char *name,
+               int name_type,
+               struct ip_service **return_iplist,
+               int *return_count)
 {
        int sock, t, i;
        char **wins_tags;
-       struct in_addr src_ip, *ip_list = NULL;
+       struct sockaddr_storage src_ss, *ss_list = NULL;
+       struct in_addr src_ip;
        NTSTATUS status;
 
        if (lp_disable_netbios()) {
-               DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
+               DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
+                                       name, name_type));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
        *return_iplist = NULL;
        *return_count = 0;
-       
-       DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
+
+       DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
+                               name, name_type));
 
        if (wins_srv_count() < 1) {
-               DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
+               DEBUG(3,("resolve_wins: WINS server resolution selected "
+                       "and no WINS servers listed.\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -886,13 +1028,28 @@ NTSTATUS resolve_wins(const char *name, int name_type,
        }
 
        /* the address we will be sending from */
-       src_ip = *interpret_addr2(lp_socket_address());
+       if (!interpret_string_addr(&src_ss, lp_socket_address(),
+                               AI_NUMERICHOST|AI_PASSIVE)) {
+               zero_addr(&src_ss, AF_INET);
+       }
+
+       if (src_ss.ss_family != AF_INET) {
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &src_ss);
+               DEBUG(3,("resolve_wins: cannot receive WINS replies "
+                       "on IPv6 address %s\n",
+                       addr));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
 
        /* in the worst case we will try every wins server with every
           tag! */
        for (t=0; wins_tags && wins_tags[t]; t++) {
                int srv_count = wins_srv_count_tag(wins_tags[t]);
                for (i=0; i<srv_count; i++) {
+                       struct sockaddr_storage wins_ss;
                        struct in_addr wins_ip;
                        int flags;
                        bool timed_out;
@@ -909,30 +1066,41 @@ NTSTATUS resolve_wins(const char *name, int name_type,
                                continue;
                        }
 
-                       DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
+                       DEBUG(3,("resolve_wins: using WINS server %s "
+                               "and tag '%s'\n",
+                               inet_ntoa(wins_ip), wins_tags[t]));
 
-                       sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
+                       sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
                        if (sock == -1) {
                                continue;
                        }
 
-                       ip_list = name_query(sock,name,name_type, False, 
-                                                   True, wins_ip, return_count, &flags, 
-                                                   &timed_out);
-                                                   
+                       in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
+                       ss_list = name_query(sock,
+                                               name,
+                                               name_type,
+                                               false,
+                                               true,
+                                               &wins_ss,
+                                               return_count,
+                                               &flags,
+                                               &timed_out);
+
                        /* exit loop if we got a list of addresses */
-                       
-                       if ( ip_list ) 
+
+                       if (ss_list)
                                goto success;
-                               
+
                        close(sock);
 
                        if (timed_out) {
-                               /* Timed out wating for WINS server to respond.  Mark it dead. */
+                               /* Timed out wating for WINS server to respond.
+                                * Mark it dead. */
                                wins_srv_died(wins_ip, src_ip);
                        } else {
                                /* The name definately isn't in this
-                                  group of WINS servers. goto the next group  */
+                                  group of WINS servers.
+                                  goto the next group  */
                                break;
                        }
                }
@@ -942,14 +1110,15 @@ NTSTATUS resolve_wins(const char *name, int name_type,
        return NT_STATUS_NO_LOGON_SERVERS;
 
 success:
+
        status = NT_STATUS_OK;
-       if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
+       if (!convert_ss2service(return_iplist, ss_list, *return_count))
                status = NT_STATUS_INVALID_PARAMETER;
-       
-       SAFE_FREE( ip_list );
+
+       SAFE_FREE(ss_list);
        wins_srv_tags_free(wins_tags);
        close(sock);
-       
+
        return status;
 }
 
@@ -964,25 +1133,26 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type,
        /*
         * "lmhosts" means parse the local lmhosts file.
         */
-       
+
        XFILE *fp;
        pstring lmhost_name;
        int name_type2;
-       struct in_addr return_ip;
+       struct sockaddr_storage return_ss;
        NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
 
        *return_iplist = NULL;
        *return_count = 0;
 
-       DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
+       DEBUG(3,("resolve_lmhosts: "
+               "Attempting lmhosts lookup for name %s<0x%x>\n",
+               name, name_type));
 
        fp = startlmhosts(dyn_LMHOSTSFILE);
 
        if ( fp == NULL )
                return NT_STATUS_NO_SUCH_FILE;
 
-       while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) 
-       {
+       while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ss)) {
 
                if (!strequal(name, lmhost_name))
                        continue;
@@ -990,7 +1160,8 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type,
                if ((name_type2 != -1) && (name_type != name_type2))
                        continue;
 
-               *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
+               *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
+                                       struct ip_service,
                                        (*return_count)+1);
 
                if ((*return_iplist) == NULL) {
@@ -999,7 +1170,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               (*return_iplist)[*return_count].ip   = return_ip;
+               (*return_iplist)[*return_count].ss = return_ss;
                (*return_iplist)[*return_count].port = PORT_NONE;
                *return_count += 1;
 
@@ -1012,7 +1183,6 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type,
        }
 
        endlmhosts(fp);
-
        return status;
 }
 
@@ -1035,14 +1205,17 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
        int i = 0;
 
        if ( name_type != 0x20 && name_type != 0x0) {
-               DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
+               DEBUG(5, ("resolve_hosts: not appropriate "
+                       "for name type <0x%x>\n",
+                       name_type));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
        *return_iplist = NULL;
        *return_count = 0;
 
-       DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
+       DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
+                               name, name_type));
 
        ZERO_STRUCT(hints);
        /* By default make sure it supports TCP. */
@@ -1060,18 +1233,14 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
        }
 
        for (res = ailist; res; res = res->ai_next) {
-               struct in_addr return_ip;
+               struct sockaddr_storage ss;
 
-               /* IPv4 only for now until I convert ip_service */
-               if (res->ai_family != AF_INET) {
-                       continue;
-               }
-               if (!res->ai_addr) {
+               if (!res->ai_addr || res->ai_addrlen == 0) {
                        continue;
                }
 
-               putip((char *)&return_ip,
-                       &((struct sockaddr_in *)res->ai_addr)->sin_addr);
+               memset(&ss, '\0', sizeof(ss));
+               memcpy(&ss, res->ai_addr, res->ai_addrlen);
 
                *return_count += 1;
 
@@ -1083,9 +1252,8 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
                        freeaddrinfo(ailist);
                        return NT_STATUS_NO_MEMORY;
                }
-               (*return_iplist)[i].ip   = return_ip;
+               (*return_iplist)[i].ss = ss;
                (*return_iplist)[i].port = PORT_NONE;
-
                i++;
        }
        if (ailist) {
@@ -1101,10 +1269,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
  Resolve via "ADS" method.
 *********************************************************/
 
-NTSTATUS resolve_ads(const char *name, int name_type,
-                    const char *sitename,
-                    struct ip_service **return_iplist,
-                    int *return_count)
+NTSTATUS resolve_ads(const char *name,
+                       int name_type,
+                       const char *sitename,
+                       struct ip_service **return_iplist,
+                       int *return_count)
 {
        int                     i, j;
        NTSTATUS                status;
@@ -1123,6 +1292,8 @@ NTSTATUS resolve_ads(const char *name, int name_type,
                return NT_STATUS_NO_MEMORY;
        }
 
+       /* The DNS code needs fixing to find IPv6 addresses... JRA. */
+
        switch (name_type) {
                case 0x1b:
                        DEBUG(5,("resolve_ads: Attempting to resolve "
@@ -1155,53 +1326,60 @@ NTSTATUS resolve_ads(const char *name, int name_type,
        for (i=0;i<numdcs;i++) {
                numaddrs += MAX(dcs[i].num_ips,1);
        }
-               
-       if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
-               DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
+
+       if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
+                       NULL ) {
+               DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
+                                       numaddrs ));
                talloc_destroy(ctx);
                return NT_STATUS_NO_MEMORY;
        }
-       
+
        /* now unroll the list of IP addresses */
 
        *return_count = 0;
        i = 0;
        j = 0;
        while ( i < numdcs && (*return_count<numaddrs) ) {
+               struct in_addr ip;
                struct ip_service *r = &(*return_iplist)[*return_count];
 
                r->port = dcs[i].port;
-               
+
                /* If we don't have an IP list for a name, lookup it up */
-               
-               if ( !dcs[i].ips ) {
-                       r->ip = *interpret_addr2(dcs[i].hostname);
+
+               if (!dcs[i].ips) {
+                       ip = *interpret_addr2(dcs[i].hostname);
                        i++;
                        j = 0;
                } else {
                        /* use the IP addresses from the SRV sresponse */
-                       
+
                        if ( j >= dcs[i].num_ips ) {
                                i++;
                                j = 0;
                                continue;
                        }
-                       
-                       r->ip = dcs[i].ips[j];
+
+                       ip = dcs[i].ips[j];
                        j++;
                }
-                       
-               /* make sure it is a valid IP.  I considered checking the negative
-                  connection cache, but this is the wrong place for it.  Maybe only
-                  as a hac.  After think about it, if all of the IP addresses retuend
-                  from DNS are dead, what hope does a netbios name lookup have?
-                  The standard reason for falling back to netbios lookups is that 
-                  our DNS server doesn't know anything about the DC's   -- jerry */    
-                          
-               if ( ! is_zero_ip_v4(r->ip) )
+
+               in_addr_to_sockaddr_storage(&r->ss, ip);
+
+               /* make sure it is a valid IP.  I considered checking the
+                * negative connection cache, but this is the wrong place
+                * for it. Maybe only as a hack. After think about it, if
+                * all of the IP addresses returned from DNS are dead, what
+                * hope does a netbios name lookup have ? The standard reason
+                * for falling back to netbios lookups is that our DNS server
+                * doesn't know anything about the DC's   -- jerry */
+
+               if (!is_zero_addr(&r->ss)) {
                        (*return_count)++;
+               }
        }
-               
+
        talloc_destroy(ctx);
        return NT_STATUS_OK;
 }
@@ -1211,23 +1389,22 @@ NTSTATUS resolve_ads(const char *name, int name_type,
  Use this function if the string is either an IP address, DNS
  or host name or NetBIOS name. This uses the name switch in the
  smb.conf to determine the order of name resolution.
+
  Added support for ip addr/port to support ADS ldap servers.
- the only place we currently care about the port is in the 
+ the only place we currently care about the port is in the
  resolve_hosts() when looking up DC's via SRV RR entries in DNS
 **********************************************************************/
 
-NTSTATUS internal_resolve_name(const char *name, int name_type,
-                              const char *sitename,
-                              struct ip_service **return_iplist,
-                              int *return_count, const char *resolve_order)
+NTSTATUS internal_resolve_name(const char *name,
+                               int name_type,
+                               const char *sitename,
+                               struct ip_service **return_iplist,
+                               int *return_count,
+                               const char *resolve_order)
 {
        pstring name_resolve_list;
        fstring tok;
        const char *ptr;
-       bool allones = (strcmp(name,"255.255.255.255") == 0);
-       bool allzeros = (strcmp(name,"0.0.0.0") == 0);
-       bool is_address = is_ipaddress_v4(name);
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        int i;
 
@@ -1237,30 +1414,29 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
        DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
                        name, name_type, sitename ? sitename : NULL));
 
-       if (allzeros || allones || is_address) {
-  
-               if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
+       if (is_ipaddress(name)) {
+               if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
+                               NULL) {
                        DEBUG(0,("internal_resolve_name: malloc fail !\n"));
                        return NT_STATUS_NO_MEMORY;
                }
-       
-               if(is_address) { 
-                       /* ignore the port here */
-                       (*return_iplist)->port = PORT_NONE;
-               
-                       /* if it's in the form of an IP address then get the lib to interpret it */
-                       if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
-                               DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
-                               SAFE_FREE(*return_iplist);
-                               return NT_STATUS_INVALID_PARAMETER;
-                       }
-               } else {
-                       (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
+
+               /* ignore the port here */
+               (*return_iplist)->port = PORT_NONE;
+
+               /* if it's in the form of an IP address then get the lib to interpret it */
+               if (!interpret_string_addr(&(*return_iplist)->ss,
+                                       name, AI_NUMERICHOST)) {
+                       DEBUG(1,("internal_resolve_name: interpret_string_addr "
+                               "failed on %s\n",
+                               name));
+                       SAFE_FREE(*return_iplist);
+                       return NT_STATUS_INVALID_PARAMETER;
                }
                *return_count = 1;
                return NT_STATUS_OK;
        }
-  
+
        /* Check name cache */
 
        if (namecache_fetch(name, name_type, return_iplist, return_count)) {
@@ -1274,25 +1450,25 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
 
        /* set the name resolution order */
 
-       if ( strcmp( resolve_order, "NULL") == 0 ) {
+       if (strcmp( resolve_order, "NULL") == 0) {
                DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
-  
-       if ( !resolve_order ) {
+
+       if (!resolve_order) {
                pstrcpy(name_resolve_list, lp_name_resolve_order());
        } else {
                pstrcpy(name_resolve_list, resolve_order);
        }
 
-       if ( !name_resolve_list[0] ) {
+       if (!name_resolve_list[0]) {
                ptr = "host";
        } else {
                ptr = name_resolve_list;
        }
 
        /* iterate through the name resolution backends */
-  
+
        while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
                if((strequal(tok, "host") || strequal(tok, "hosts"))) {
                        status = resolve_hosts(name, name_type, return_iplist,
@@ -1301,18 +1477,19 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
                                goto done;
                        }
                } else if(strequal( tok, "kdc")) {
-                       /* deal with KDC_NAME_TYPE names here.  This will result in a
-                               SRV record lookup */
+                       /* deal with KDC_NAME_TYPE names here.
+                        * This will result in a SRV record lookup */
                        status = resolve_ads(name, KDC_NAME_TYPE, sitename,
                                             return_iplist, return_count);
                        if (NT_STATUS_IS_OK(status)) {
-                               /* Ensure we don't namecache this with the KDC port. */
+                               /* Ensure we don't namecache
+                                * this with the KDC port. */
                                name_type = KDC_NAME_TYPE;
                                goto done;
                        }
                } else if(strequal( tok, "ads")) {
-                       /* deal with 0x1c and 0x1b names here.  This will result in a
-                               SRV record lookup */
+                       /* deal with 0x1c and 0x1b names here.
+                        * This will result in a SRV record lookup */
                        status = resolve_ads(name, name_type, sitename,
                                             return_iplist, return_count);
                        if (NT_STATUS_IS_OK(status)) {
@@ -1362,29 +1539,43 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
        the iplist when the PDC is down will cause two sets of timeouts. */
 
        if ( *return_count ) {
-               *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
+               *return_count = remove_duplicate_addrs2(*return_iplist,
+                                       *return_count );
        }
+
        /* Save in name cache */
        if ( DEBUGLEVEL >= 100 ) {
-               for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
-                       DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
-                               name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+               for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr),
+                                       &(*return_iplist)[i].ss);
+                       DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
+                                       name,
+                                       name_type,
+                                       addr,
+                                       (*return_iplist)[i].port));
+               }
        }
-   
+
        namecache_store(name, name_type, *return_count, *return_iplist);
 
        /* Display some debugging info */
 
        if ( DEBUGLEVEL >= 10 ) {
-               DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
+               DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
+                                       *return_count));
 
                for (i = 0; i < *return_count; i++) {
-                       DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr),
+                                       &(*return_iplist)[i].ss);
+                       DEBUGADD(10, ("%s:%d ",
+                                       addr,
+                                       (*return_iplist)[i].port));
                }
                DEBUG(10, ("\n"));
        }
-  
+
        return status;
 }
 
@@ -1395,39 +1586,38 @@ NTSTATUS internal_resolve_name(const char *name, int name_type,
  smb.conf to determine the order of name resolution.
 *********************************************************/
 
-bool resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+bool resolve_name(const char *name,
+               struct sockaddr_storage *return_ss,
+               int name_type)
 {
-       struct ip_service *ip_list = NULL;
-       char *sitename = sitename_fetch(lp_realm()); /* wild guess */
+       struct ip_service *ss_list = NULL;
+       char *sitename = NULL;
        int count = 0;
 
-       if (is_ipaddress_v4(name)) {
-               *return_ip = *interpret_addr2(name);
-               SAFE_FREE(sitename);
-               return True;
+       if (is_ipaddress(name)) {
+               return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
        }
 
+       sitename = sitename_fetch(lp_realm()); /* wild guess */
+
        if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
-                                                 &ip_list, &count,
+                                                 &ss_list, &count,
                                                  lp_name_resolve_order()))) {
                int i;
-               
+
                /* only return valid addresses for TCP connections */
                for (i=0; i<count; i++) {
-                       char *ip_str = inet_ntoa(ip_list[i].ip);
-                       if (ip_str &&
-                           strcmp(ip_str, "255.255.255.255") != 0 &&
-                           strcmp(ip_str, "0.0.0.0") != 0) 
-                       {
-                               *return_ip = ip_list[i].ip;
-                               SAFE_FREE(ip_list);
+                       if (!is_zero_addr(&ss_list[i].ss) &&
+                                       !is_broadcast_addr(&ss_list[i].ss)) {
+                               *return_ss = ss_list[i].ss;
+                               SAFE_FREE(ss_list);
                                SAFE_FREE(sitename);
                                return True;
                        }
                }
        }
-       
-       SAFE_FREE(ip_list);
+
+       SAFE_FREE(ss_list);
        SAFE_FREE(sitename);
        return False;
 }
@@ -1436,7 +1626,7 @@ bool resolve_name(const char *name, struct in_addr *return_ip, int name_type)
  Find the IP address of the master browser or DMB for a workgroup.
 *********************************************************/
 
-bool find_master_ip(const char *group, struct in_addr *master_ip)
+bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
 {
        struct ip_service *ip_list = NULL;
        int count = 0;
@@ -1444,27 +1634,27 @@ bool find_master_ip(const char *group, struct in_addr *master_ip)
 
        if (lp_disable_netbios()) {
                DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
-               return False;
+               return false;
        }
 
        status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
                                       lp_name_resolve_order());
        if (NT_STATUS_IS_OK(status)) {
-               *master_ip = ip_list[0].ip;
+               *master_ss = ip_list[0].ss;
                SAFE_FREE(ip_list);
-               return True;
+               return true;
        }
 
        status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
                                       lp_name_resolve_order());
        if (NT_STATUS_IS_OK(status)) {
-               *master_ip = ip_list[0].ip;
+               *master_ss = ip_list[0].ss;
                SAFE_FREE(ip_list);
-               return True;
+               return true;
        }
 
        SAFE_FREE(ip_list);
-       return False;
+       return false;
 }
 
 /********************************************************
@@ -1472,7 +1662,7 @@ bool find_master_ip(const char *group, struct in_addr *master_ip)
  for a domain.
 *********************************************************/
 
-bool get_pdc_ip(const char *domain, struct in_addr *ip)
+bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
 {
        struct ip_service *ip_list = NULL;
        int count = 0;
@@ -1490,7 +1680,7 @@ bool get_pdc_ip(const char *domain, struct in_addr *ip)
                                               &count,
                                               lp_name_resolve_order());
                if (!NT_STATUS_IS_OK(status)) {
-                       return False;
+                       return false;
                }
        }
 
@@ -1498,15 +1688,13 @@ bool get_pdc_ip(const char *domain, struct in_addr *ip)
           multi-homed PDC and not a mess up */
 
        if ( count > 1 ) {
-               DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
-               sort_ip_list2( ip_list, count );
+               DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
+               sort_service_list(ip_list, count);
        }
 
-       *ip = ip_list[0].ip;
-       
+       *pss = ip_list[0].ss;
        SAFE_FREE(ip_list);
-
-       return True;
+       return true;
 }
 
 /* Private enum type for lookups. */
@@ -1518,8 +1706,12 @@ enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
  a domain.
 *********************************************************/
 
-static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, 
-                            int *count, enum dc_lookup_type lookup_type, bool *ordered)
+static NTSTATUS get_dc_list(const char *domain,
+                       const char *sitename,
+                       struct ip_service **ip_list,
+                       int *count,
+                       enum dc_lookup_type lookup_type,
+                       bool *ordered)
 {
        fstring resolve_order;
        char *saf_servername;
@@ -1544,56 +1736,56 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
           are disabled and ads_only is True, then set the string to
           NULL. */
 
-       fstrcpy( resolve_order, lp_name_resolve_order() );
-       strlower_m( resolve_order );
-       if ( lookup_type == DC_ADS_ONLY)  {
-               if ( strstr( resolve_order, "host" ) ) {
-                       fstrcpy( resolve_order, "ads" );
+       fstrcpy(resolve_order, lp_name_resolve_order());
+       strlower_m(resolve_order);
+       if (lookup_type == DC_ADS_ONLY)  {
+               if (strstr( resolve_order, "host")) {
+                       fstrcpy( resolve_order, "ads");
 
                        /* DNS SRV lookups used by the ads resolver
                           are already sorted by priority and weight */
-                       *ordered = True;
+                       *ordered = true;
                } else {
-                        fstrcpy( resolve_order, "NULL" );
+                        fstrcpy(resolve_order, "NULL");
                }
        } else if (lookup_type == DC_KDC_ONLY) {
                /* DNS SRV lookups used by the ads/kdc resolver
                   are already sorted by priority and weight */
-               *ordered = True;
-               fstrcpy( resolve_order, "kdc" );
+               *ordered = true;
+               fstrcpy(resolve_order, "kdc");
        }
 
-       /* fetch the server we have affinity for.  Add the 
+       /* fetch the server we have affinity for.  Add the
           'password server' list to a search for our domain controllers */
-       
+
        saf_servername = saf_fetch( domain);
-       
-       if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
-               pstr_sprintf( pserver, "%s, %s", 
+
+       if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
+               pstr_sprintf(pserver, "%s, %s",
                        saf_servername ? saf_servername : "",
-                       lp_passwordserver() );
+                       lp_passwordserver());
        } else {
-               pstr_sprintf( pserver, "%s, *", 
-                       saf_servername ? saf_servername : "" );
+               pstr_sprintf(pserver, "%s, *",
+                       saf_servername ? saf_servername : "");
        }
 
        SAFE_FREE( saf_servername );
 
        /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
 
-       if ( !*pserver ) {
+       if (!*pserver ) {
                DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
                return internal_resolve_name(domain, 0x1C, sitename, ip_list,
                                             count, resolve_order);
        }
 
        DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
-       
+
        /*
         * if '*' appears in the "password server" list then add
         * an auto lookup to the list of manually configured
-        * DC's.  If any DC is listed by name, then the list should be 
-        * considered to be ordered 
+        * DC's.  If any DC is listed by name, then the list should be
+        * considered to be ordered
         */
 
        p = pserver;
@@ -1606,8 +1798,9 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
                        if (NT_STATUS_IS_OK(status)) {
                                num_addresses += auto_count;
                        }
-                       done_auto_lookup = True;
-                       DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
+                       done_auto_lookup = true;
+                       DEBUG(8,("Adding %d DC's from auto lookup\n",
+                                               auto_count));
                } else  {
                        num_addresses++;
                }
@@ -1615,10 +1808,10 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
 
        /* if we have no addresses and haven't done the auto lookup, then
           just return the list of DC's.  Or maybe we just failed. */
-                  
-       if ( (num_addresses == 0) ) {
-               if ( done_auto_lookup ) {
-                       DEBUG(4,("get_dc_list: no servers found\n")); 
+
+       if ((num_addresses == 0)) {
+               if (done_auto_lookup) {
+                       DEBUG(4,("get_dc_list: no servers found\n"));
                        SAFE_FREE(auto_ip_list);
                        return NT_STATUS_NO_LOGON_SERVERS;
                }
@@ -1626,7 +1819,8 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
                                             count, resolve_order);
        }
 
-       if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
+       if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
+                                       num_addresses)) == NULL) {
                DEBUG(3,("get_dc_list: malloc fail !\n"));
                SAFE_FREE(auto_ip_list);
                return NT_STATUS_NO_MEMORY;
@@ -1636,74 +1830,101 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
        local_count = 0;
 
        /* fill in the return list now with real IP's */
-                               
-       while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
-               struct in_addr name_ip;
-                       
+
+       while ((local_count<num_addresses) &&
+                       next_token(&p,name,LIST_SEP,sizeof(name))) {
+               struct sockaddr_storage name_ss;
+
                /* copy any addersses from the auto lookup */
-                       
-               if ( strequal(name, "*") ) {
-                       for ( j=0; j<auto_count; j++ ) {
-                               /* Check for and don't copy any known bad DC IP's. */
-                               if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, 
-                                               inet_ntoa(auto_ip_list[j].ip)))) {
-                                       DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
-                                               inet_ntoa(auto_ip_list[j].ip) ));
+
+               if (strequal(name, "*")) {
+                       for (j=0; j<auto_count; j++) {
+                               char addr[INET6_ADDRSTRLEN];
+                               print_sockaddr(addr,
+                                               sizeof(addr),
+                                               &auto_ip_list[j].ss);
+                               /* Check for and don't copy any
+                                * known bad DC IP's. */
+                               if(!NT_STATUS_IS_OK(check_negative_conn_cache(
+                                               domain,
+                                               addr))) {
+                                       DEBUG(5,("get_dc_list: "
+                                               "negative entry %s removed "
+                                               "from DC list\n",
+                                               addr));
                                        continue;
                                }
-                               return_iplist[local_count].ip   = auto_ip_list[j].ip;
-                               return_iplist[local_count].port = auto_ip_list[j].port;
+                               return_iplist[local_count].ss =
+                                       auto_ip_list[j].ss;
+                               return_iplist[local_count].port =
+                                       auto_ip_list[j].port;
                                local_count++;
                        }
                        continue;
                }
-                       
-                       
-               /* added support for address:port syntax for ads (not that I think 
-                  anyone will ever run the LDAP server in an AD domain on something 
-                  other than port 389 */
-                       
+
+               /* added support for address:port syntax for ads
+                * (not that I think anyone will ever run the LDAP
+                * server in an AD domain on something other than
+                * port 389 */
+
                port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
-               if ( (port_str=strchr(name, ':')) != NULL ) {
+               if ((port_str=strchr(name, ':')) != NULL) {
                        *port_str = '\0';
                        port_str++;
-                       port = atoi( port_str );
+                       port = atoi(port_str);
                }
 
-               /* explicit lookup; resolve_name() will handle names & IP addresses */
-               if ( resolve_name( name, &name_ip, 0x20 ) ) {
+               /* explicit lookup; resolve_name() will
+                * handle names & IP addresses */
+               if (resolve_name( name, &name_ss, 0x20 )) {
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr,
+                                       sizeof(addr),
+                                       &name_ss);
 
                        /* Check for and don't copy any known bad DC IP's. */
-                       if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
-                               DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
+                       if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
+                                                       addr)) ) {
+                               DEBUG(5,("get_dc_list: negative entry %s "
+                                       "removed from DC list\n",
+                                       name ));
                                continue;
                        }
 
-                       return_iplist[local_count].ip   = name_ip;
+                       return_iplist[local_count].ss = name_ss;
                        return_iplist[local_count].port = port;
                        local_count++;
-                       *ordered = True;
+                       *ordered = true;
                }
        }
-                               
+
        SAFE_FREE(auto_ip_list);
 
-       /* need to remove duplicates in the list if we have any 
+       /* need to remove duplicates in the list if we have any
           explicit password servers */
-          
-       if ( local_count ) {
-               local_count = remove_duplicate_addrs2( return_iplist, local_count );
+
+       if (local_count) {
+               local_count = remove_duplicate_addrs2(return_iplist,
+                               local_count );
        }
-               
+
        if ( DEBUGLEVEL >= 4 ) {
-               DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
-                       *ordered ? "":"un"));
+               DEBUG(4,("get_dc_list: returning %d ip addresses "
+                               "in an %sordered list\n",
+                               local_count,
+                               *ordered ? "":"un"));
                DEBUG(4,("get_dc_list: "));
-               for ( i=0; i<local_count; i++ )
-                       DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
+               for ( i=0; i<local_count; i++ ) {
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr,
+                                       sizeof(addr),
+                                       &return_iplist[i].ss);
+                       DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
+               }
                DEBUGADD(4,("\n"));
        }
-                       
+
        *ip_list = return_iplist;
        *count = local_count;
 
@@ -1714,32 +1935,37 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_
  Small wrapper function to get the DC list and sort it if neccessary.
 *********************************************************************/
 
-NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, bool ads_only )
+NTSTATUS get_sorted_dc_list( const char *domain,
+                       const char *sitename,
+                       struct ip_service **ip_list,
+                       int *count,
+                       bool ads_only )
 {
        bool ordered;
        NTSTATUS status;
        enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
 
-       DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
-               "using [%s]\n",
+       DEBUG(8,("get_sorted_dc_list: attempting lookup "
+               "for name %s (sitename %s) using [%s]\n",
                domain,
                sitename ? sitename : "NULL",
                (ads_only ? "ads" : lp_name_resolve_order())));
-       
+
        if (ads_only) {
                lookup_type = DC_ADS_ONLY;
        }
 
-       status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
+       status = get_dc_list(domain, sitename, ip_list,
+                       count, lookup_type, &ordered);
        if (!NT_STATUS_IS_OK(status)) {
-               return status; 
+               return status;
        }
-               
+
        /* only sort if we don't already have an ordered list */
-       if ( !ordered ) {
-               sort_ip_list2( *ip_list, *count );
+       if (!ordered) {
+               sort_service_list(*ip_list, *count);
        }
-               
+
        return NT_STATUS_OK;
 }
 
@@ -1747,7 +1973,10 @@ NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip
  Get the KDC list - re-use all the logic in get_dc_list.
 *********************************************************************/
 
-NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
+NTSTATUS get_kdc_list( const char *realm,
+                       const char *sitename,
+                       struct ip_service **ip_list,
+                       int *count)
 {
        bool ordered;
        NTSTATUS status;
@@ -1755,15 +1984,16 @@ NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_servic
        *count = 0;
        *ip_list = NULL;
 
-       status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
+       status = get_dc_list(realm, sitename, ip_list,
+                       count, DC_KDC_ONLY, &ordered);
 
        if (!NT_STATUS_IS_OK(status)) {
-               return status; 
+               return status;
        }
 
        /* only sort if we don't already have an ordered list */
        if ( !ordered ) {
-               sort_ip_list2( *ip_list, *count );
+               sort_service_list(*ip_list, *count);
        }
 
        return NT_STATUS_OK;
index 16d8414b8f0bf7460fda4d811ea791c5ad26ad9d..0fa4b93990d1e932d277601d2b6c320763f233f2 100644 (file)
@@ -48,12 +48,13 @@ static bool is_our_primary_domain(const char *domain)
  
 static bool ads_dc_name(const char *domain,
                        const char *realm,
-                       struct in_addr *dc_ip,
+                       struct sockaddr_storage *dc_ss,
                        fstring srv_name)
 {
        ADS_STRUCT *ads;
        char *sitename;
        int i;
+       char addr[INET6_ADDRSTRLEN];
 
        if (!realm && strequal(domain, lp_workgroup())) {
                realm = lp_realm();
@@ -107,12 +108,12 @@ static bool ads_dc_name(const char *domain,
                                create_local_private_krb5_conf_for_domain(realm,
                                                                        domain,
                                                                        sitename,
-                                                                       ads->ldap.ip);
+                                                                       &ads->ldap.ss);
                        } else {
                                create_local_private_krb5_conf_for_domain(realm,
                                                                        domain,
                                                                        NULL,
-                                                                       ads->ldap.ip);
+                                                                       &ads->ldap.ss);
                        }
                }
 #endif
@@ -131,34 +132,36 @@ static bool ads_dc_name(const char *domain,
        fstrcpy(srv_name, ads->config.ldap_server_name);
        strupper_m(srv_name);
 #ifdef HAVE_ADS
-       *dc_ip = ads->ldap.ip;
+       *dc_ss = ads->ldap.ss;
 #else
-       ZERO_STRUCT(*dc_ip);
+       zero_addr(dc_ss,AF_INET);
 #endif
        ads_destroy(&ads);
-       
+
+       print_sockaddr(addr, sizeof(addr), dc_ss);
        DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
-                srv_name, inet_ntoa(*dc_ip)));
-       
+                srv_name, addr));
+
        return True;
 }
 
 /****************************************************************************
- Utility function to return the name of a DC. The name is guaranteed to be 
- valid since we have already done a name_status_find on it 
+ Utility function to return the name of a DC. The name is guaranteed to be
+ valid since we have already done a name_status_find on it
  ***************************************************************************/
 
-static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+static bool rpc_dc_name(const char *domain,
+                       fstring srv_name,
+                       struct sockaddr_storage *ss_out)
 {
        struct ip_service *ip_list = NULL;
-       struct in_addr dc_ip, exclude_ip;
+       struct sockaddr_storage dc_ss;
        int count, i;
        NTSTATUS result;
-       
-       zero_ip_v4(&exclude_ip);
+       char addr[INET6_ADDRSTRLEN];
 
        /* get a list of all domain controllers */
-       
+
        if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count,
                                                False))) {
                DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
@@ -168,35 +171,34 @@ static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
        /* Remove the entry we've already failed with (should be the PDC). */
 
        for (i = 0; i < count; i++) {
-               if (is_zero_ip_v4(ip_list[i].ip))
+               if (is_zero_addr(&ip_list[i].ss))
                        continue;
 
-               if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
+               if (name_status_find(domain, 0x1c, 0x20, &ip_list[i].ss, srv_name)) {
                        result = check_negative_conn_cache( domain, srv_name );
                        if ( NT_STATUS_IS_OK(result) ) {
-                               dc_ip = ip_list[i].ip;
+                               dc_ss = ip_list[i].ss;
                                goto done;
                        }
                }
        }
-       
 
        SAFE_FREE(ip_list);
 
        /* No-one to talk to )-: */
        return False;           /* Boo-hoo */
-       
+
  done:
        /* We have the netbios name and IP address of a domain controller.
           Ideally we should sent a SAMLOGON request to determine whether
           the DC is alive and kicking.  If we can catch a dead DC before
           performing a cli_connect() we can avoid a 30-second timeout. */
 
+       print_sockaddr(addr, sizeof(addr), &dc_ss);
        DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
-                 inet_ntoa(dc_ip), domain));
-
-       *ip_out = dc_ip;
+                 addr, domain));
 
+       *ss_out = dc_ss;
        SAFE_FREE(ip_list);
 
        return True;
@@ -206,37 +208,40 @@ static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
  wrapper around ads and rpc methods of finds DC's
 **********************************************************************/
 
-bool get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out)
+bool get_dc_name(const char *domain,
+               const char *realm,
+               fstring srv_name,
+               struct sockaddr_storage *ss_out)
 {
-       struct in_addr dc_ip;
+       struct sockaddr_storage dc_ss;
        bool ret;
        bool our_domain = False;
 
-       zero_ip_v4(&dc_ip);
+       zero_addr(&dc_ss, AF_INET);
 
        ret = False;
-       
+
        if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) )
                our_domain = True;
-       
-       /* always try to obey what the admin specified in smb.conf 
+
+       /* always try to obey what the admin specified in smb.conf
           (for the local domain) */
-       
+
        if ( (our_domain && lp_security()==SEC_ADS) || realm ) {
-               ret = ads_dc_name(domain, realm, &dc_ip, srv_name);
+               ret = ads_dc_name(domain, realm, &dc_ss, srv_name);
        }
 
        if (!domain) {
                /* if we have only the realm we can't do anything else */
                return False;
        }
-       
+
        if (!ret) {
                /* fall back on rpc methods if the ADS methods fail */
-               ret = rpc_dc_name(domain, srv_name, &dc_ip);
+               ret = rpc_dc_name(domain, srv_name, &dc_ss);
        }
-               
-       *ip_out = dc_ip;
+
+       *ss_out = dc_ss;
 
        return ret;
 }
index 4d21258f99c114f38ad9a5d333f8cc57398bc086..7e152ab3247ed1d51b0290c0035f7a90420e2ed6 100644 (file)
@@ -1187,19 +1187,20 @@ bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
 }
 
 /****************************************************************************
- Return the number of bits that match between two 4 character buffers
+ Return the number of bits that match between two len character buffers
 ***************************************************************************/
 
-int matching_quad_bits(unsigned char *p1, unsigned char *p2)
+int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
 {
-       int i, j, ret = 0;
-       for (i=0; i<4; i++) {
+       size_t i, j;
+       int ret = 0;
+       for (i=0; i<len; i++) {
                if (p1[i] != p2[i])
                        break;
                ret += 8;
        }
 
-       if (i==4)
+       if (i==len)
                return ret;
 
        for (j=0; j<8; j++) {
@@ -1219,8 +1220,8 @@ static unsigned char sort_ip[4];
 
 static int name_query_comp(unsigned char *p1, unsigned char *p2)
 {
-       return matching_quad_bits(p2+2, sort_ip) -
-               matching_quad_bits(p1+2, sort_ip);
+       return matching_len_bits(p2+2, sort_ip, 4) -
+               matching_len_bits(p1+2, sort_ip, 4);
 }
 
 /****************************************************************************
index 83cfc3efbfb354bc8ad1990f570d76350fc71f3f..f5057ec73b8032fae1945796a56177dfe791baa4 100644 (file)
@@ -30,14 +30,14 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
        struct nmb_name calling, called;
        struct cli_state *cli;
        struct rpc_pipe_client *pipe_hnd;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
 
        NTSTATUS result;
        bool pass_must_change = False;
 
        *err_str = '\0';
 
-       if(!resolve_name( remote_machine, &ip, 0x20)) {
+       if(!resolve_name( remote_machine, &ss, 0x20)) {
                slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n",
                        remote_machine );
                return NT_STATUS_UNSUCCESSFUL;
@@ -48,7 +48,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
                return NT_STATUS_NO_MEMORY;
        }
 
-       result = cli_connect(cli, remote_machine, &ip);
+       result = cli_connect(cli, remote_machine, &ss);
        if (!NT_STATUS_IS_OK(result)) {
                slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n",
                        remote_machine, nt_errstr(result) );
index e82d24426d70b554319b842087295bbe0f6feaf7..732dc78c75ea6687f30a35419f7514ecd65b8c9f 100644 (file)
@@ -147,7 +147,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
        POLICY_HND      pol;
        NTSTATUS        result = NT_STATUS_UNSUCCESSFUL;
        fstring         dc_name;
-       struct in_addr  dc_ip;
+       struct sockaddr_storage dc_ss;
        uint32          enum_ctx = 0;
        struct cli_state *cli = NULL;
        struct rpc_pipe_client *lsa_pipe;
@@ -159,7 +159,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
 
        /* lookup a DC first */
 
-       if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
+       if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
                DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
                        domain));
                return False;
@@ -167,7 +167,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
 
        /* setup the anonymous connection */
 
-       result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
+       result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC",
                "", "", "", 0, Undefined, &retry);
        if ( !NT_STATUS_IS_OK(result) )
                goto done;
index fe69587a4bac8015e85a15a72bd076262dd2bd30..c6be4914da0fb41aeaa34e3131d3b0c5fd1e7da8 100644 (file)
@@ -210,21 +210,22 @@ static bool reload_interfaces(time_t t)
                if (is_loopback_addr(&iface->ip)) {
                        DEBUG(2,("reload_interfaces: Ignoring loopback "
                                "interface %s\n",
-                               print_sockaddr(str, sizeof(str),
-                                       &iface->ip, sizeof(iface->ip)) ));
+                               print_sockaddr(str, sizeof(str), &iface->ip) ));
                        continue;
                }
 
                for (subrec=subnetlist; subrec; subrec=subrec->next) {
-                       if (ip_equal(ip, subrec->myip) &&
-                           ip_equal(nmask, subrec->mask_ip)) break;
+                       if (ip_equal_v4(ip, subrec->myip) &&
+                           ip_equal_v4(nmask, subrec->mask_ip)) {
+                               break;
+                       }
                }
 
                if (!subrec) {
                        /* it wasn't found! add it */
-                       DEBUG(2,("Found new interface %s\n", 
-                                print_sockaddr(str, sizeof(str),
-                                        &iface->ip, sizeof(iface->ip)) ));
+                       DEBUG(2,("Found new interface %s\n",
+                                print_sockaddr(str,
+                                        sizeof(str), &iface->ip) ));
                        subrec = make_normal_subnet(iface);
                        if (subrec)
                                register_my_workgroup_one_subnet(subrec);
@@ -247,8 +248,10 @@ static bool reload_interfaces(time_t t)
                        }
                        ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
                        nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
-                       if (ip_equal(ip, subrec->myip) &&
-                           ip_equal(nmask, subrec->mask_ip)) break;
+                       if (ip_equal_v4(ip, subrec->myip) &&
+                           ip_equal_v4(nmask, subrec->mask_ip)) {
+                               break;
+                       }
                }
                if (n == -1) {
                        /* oops, an interface has disapeared. This is
@@ -257,12 +260,12 @@ static bool reload_interfaces(time_t t)
                         instead we just wear the memory leak and
                         remove it from the list of interfaces without
                         freeing it */
-                       DEBUG(2,("Deleting dead interface %s\n", 
+                       DEBUG(2,("Deleting dead interface %s\n",
                                 inet_ntoa(subrec->myip)));
                        close_subnet(subrec);
                }
        }
-       
+
        rescan_listen_set = True;
 
        /* We need to shutdown if there are no subnets... */
@@ -376,7 +379,7 @@ static void msg_nmbd_send_packet(struct messaging_context *msg,
 
        for (subrec = FIRST_SUBNET; subrec != NULL;
             subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               if (ip_equal(*local_ip, subrec->myip)) {
+               if (ip_equal_v4(*local_ip, subrec->myip)) {
                        p->fd = (p->packet_type == NMB_PACKET) ?
                                subrec->nmb_sock : subrec->dgram_sock;
                        break;
@@ -642,6 +645,9 @@ static void process(void)
 
 static bool open_sockets(bool isdaemon, int port)
 {
+       struct sockaddr_storage ss;
+       const char *sock_addr = lp_socket_address();
+
        /*
         * The sockets opened here will be used to receive broadcast
         * packets *only*. Interface specific sockets are opened in
@@ -650,19 +656,34 @@ static bool open_sockets(bool isdaemon, int port)
         * now deprecated.
         */
 
-       if ( isdaemon )
+       if (!interpret_string_addr(&ss, sock_addr,
+                               AI_NUMERICHOST|AI_PASSIVE)) {
+               DEBUG(0,("open_sockets: unable to get socket address "
+                       "from string %s", sock_addr));
+               return false;
+       }
+       if (ss.ss_family != AF_INET) {
+               DEBUG(0,("open_sockets: unable to use IPv6 socket"
+                       "%s in nmbd\n",
+                       sock_addr));
+               return false;
+       }
+
+       if (isdaemon) {
                ClientNMB = open_socket_in(SOCK_DGRAM, port,
-                                          0, interpret_addr(lp_socket_address()),
-                                          True);
-       else
+                                          0, &ss,
+                                          true);
+       } else {
                ClientNMB = 0;
-  
+       }
+
        ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
-                                          3, interpret_addr(lp_socket_address()),
-                                          True);
+                                          3, &ss,
+                                          true);
 
-       if ( ClientNMB == -1 )
-               return( False );
+       if (ClientNMB == -1) {
+               return false;
+       }
 
        /* we are never interested in SIGPIPE */
        BlockSignals(True,SIGPIPE);
@@ -744,7 +765,7 @@ static bool open_sockets(bool isdaemon, int port)
        };
        poptFreeContext(pc);
 
-       global_in_nmbd = True;
+       global_in_nmbd = true;
        
        StartupTime = time(NULL);
        
index fb87927436d745b60f04202ca40688e6038cc56f..a0b2ef15f8b804c6e2a2be874d3304969c6df84f 100644 (file)
@@ -219,7 +219,7 @@ static void become_domain_master_query_success(struct subnet_record *subrec,
 
        allones_ip.s_addr = htonl(INADDR_BROADCAST);
 
-       if(ismyip_v4(ip) || ip_equal(allones_ip, ip) || is_zero_ip_v4(ip)) {
+       if(ismyip_v4(ip) || ip_equal_v4(allones_ip, ip) || is_zero_ip_v4(ip)) {
                if( DEBUGLVL( 3 ) ) {
                        dbgtext( "become_domain_master_query_success():\n" );
                        dbgtext( "Our address (%s) ", inet_ntoa(ip) );
index e141b3e288eea36ac2a9e98735c9c06f244a079a..4effce07222f6259ac1d392668237f44d154ec90 100644 (file)
@@ -291,7 +291,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
 
   /* First check if we already have a dmb for this workgroup. */
 
-       if(!is_zero_ip_v4(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+       if(!is_zero_ip_v4(work->dmb_addr) && ip_equal_v4(work->dmb_addr, answer_ip)) {
                /* Do the local master browser announcement to the domain
                        master browser name and IP. */
                announce_local_master_browser_to_domain_master_browser( work );
index 8dda58e35227db8f8a9ac4948fa05414a82e2120..51e4858f32917d51e8f204da859c8a0c5c0c8a6d 100644 (file)
@@ -32,7 +32,7 @@ void load_lmhosts_file(const char *fname)
 {  
        pstring name;
        int name_type;
-       struct in_addr ipaddr;
+       struct sockaddr_storage ss;
        XFILE *fp = startlmhosts( fname );
 
        if (!fp) {
@@ -41,10 +41,17 @@ void load_lmhosts_file(const char *fname)
                return;
        }
    
-       while (getlmhostsent(fp, name, &name_type, &ipaddr) ) {
+       while (getlmhostsent(fp, name, &name_type, &ss) ) {
+               struct in_addr ipaddr;
                struct subnet_record *subrec = NULL;
                enum name_source source = LMHOSTS_NAME;
 
+               if (ss.ss_family != AF_INET) {
+                       continue;
+               }
+
+               ipaddr = ((struct sockaddr_in *)&ss)->sin_addr;
+
                /* We find a relevent subnet to put this entry on, then add it. */
                /* Go through all the broadcast subnets and see if the mask matches. */
                for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
index 46a9830b25187fc90625ec76ba5972a25d5c8263..ae5f766e66954eaa91daf0ee5810495d6c0ef005 100644 (file)
@@ -338,7 +338,7 @@ bool find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
        int i;
 
        for(i = 0; i < namerec->data.num_ips; i++) {
-               if(ip_equal( namerec->data.ip[i], ip)) {
+               if(ip_equal_v4( namerec->data.ip[i], ip)) {
                        return True;
                }
        }
@@ -391,7 +391,7 @@ void remove_ip_from_name_record( struct name_record *namerec,
        int orig_num = namerec->data.num_ips;
 
        for(i = 0; i < orig_num; i++) {
-               if( ip_equal( remove_ip, namerec->data.ip[i]) ) {
+               if( ip_equal_v4( remove_ip, namerec->data.ip[i]) ) {
                        remove_nth_ip_in_record( namerec, i);
                        break;
                }
index b7f5a3d45b0fde32a7aa42dfb8ceadd9552997ec..edcf258519bec148919f3aaa708e2d76d32518a9 100644 (file)
@@ -361,7 +361,7 @@ static void wins_next_registration(struct response_record *rrec)
        tag = (const char *)userdata->data;
 
        for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
-               if (ip_equal(last_ip, subrec->myip)) {
+               if (ip_equal_v4(last_ip, subrec->myip)) {
                        subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
                        break;
                }
index b19b1d35994ade0691973dfe427031e87af12e87..d49c8bab799318ed28f316a19ada9ae111ccdb9e 100644 (file)
@@ -50,7 +50,7 @@ static int find_subnet_fd_for_address( struct in_addr local_ip )
        struct subnet_record *subrec;
 
        for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
-               if(ip_equal(local_ip, subrec->myip))
+               if(ip_equal_v4(local_ip, subrec->myip))
                        return subrec->nmb_sock;
 
        return ClientNMB;
@@ -65,7 +65,7 @@ static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
        struct subnet_record *subrec;
 
        for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
-               if(ip_equal(local_ip, subrec->myip))
+               if(ip_equal_v4(local_ip, subrec->myip))
                        return subrec->dgram_sock;
 
        return ClientDGRAM;
index 39aa4577bb5347b992ffa041e70220876da64a25..d100ad482a0edd11d93f60d88f410fe4a022c451 100644 (file)
@@ -85,13 +85,17 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
                nmb_sock = -1;
                dgram_sock = -1;
        } else {
+               struct sockaddr_storage ss;
+
+               in_addr_to_sockaddr_storage(&ss, myip);
+
                /*
                 * Attempt to open the sockets on port 137/138 for this interface
                 * and bind them.
                 * Fail the subnet creation if this fails.
                 */
 
-               if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
+               if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, &ss,true)) == -1) {
                        if( DEBUGLVL( 0 ) ) {
                                Debug1( "nmbd_subnetdb:make_subnet()\n" );
                                Debug1( "  Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
@@ -101,7 +105,7 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
                        return NULL;
                }
 
-               if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
+               if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, &ss, true)) == -1) {
                        if( DEBUGLVL( 0 ) ) {
                                Debug1( "nmbd_subnetdb:make_subnet()\n" );
                                Debug1( "  Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
index df71e6db437baa7257990e9c9d6d05fd293e2997..aaa56f92169dc7c6abb974ec1493af45be49da66 100644 (file)
@@ -70,6 +70,7 @@ static void sync_child(char *name, int nm_type,
        struct cli_state *cli;
        uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
        struct nmb_name called, calling;
+       struct sockaddr_storage ss;
        NTSTATUS status;
 
        /* W2K DMB's return empty browse lists on port 445. Use 139.
@@ -85,7 +86,8 @@ static void sync_child(char *name, int nm_type,
                return;
        }
 
-       status = cli_connect(cli, name, &ip);
+       in_addr_to_sockaddr_storage(&ss, ip);
+       status = cli_connect(cli, name, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                return;
        }
index 38962c2b3941f954208d9043ab328f06d670e7d5..70303af48b15537c1767f7314c1130aec919cfe0 100644 (file)
@@ -914,7 +914,7 @@ void wins_process_name_refresh_request( struct subnet_record *subrec,
                 * if the record is a replica:
                 * we take ownership and update the version ID.
                 */
-               if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+               if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
                        update_wins_owner(namerec, our_fake_ip);
                        get_global_id_and_update(&namerec->data.id, True);
                }
@@ -1030,7 +1030,7 @@ static void wins_register_query_fail(struct subnet_record *subrec,
        namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
 
        if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
-                       ip_equal(rrec->packet->ip, *namerec->data.ip)) {
+                       ip_equal_v4(rrec->packet->ip, *namerec->data.ip)) {
                remove_name_from_namelist( subrec, namerec);
                namerec = NULL;
        }
@@ -1304,8 +1304,8 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
        if( !registering_group_name
                        && (namerec != NULL)
                        && (namerec->data.num_ips == 1)
-                       && ip_equal( namerec->data.ip[0], from_ip )
-                       && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
+                       && ip_equal_v4( namerec->data.ip[0], from_ip )
+                       && ip_equal_v4(namerec->data.wins_ip, our_fake_ip) ) {
                update_name_ttl( namerec, ttl );
                wins_hook("refresh", namerec, ttl);
                send_wins_name_registration_response( 0, ttl, p );
@@ -1633,7 +1633,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
                 * If it's a replica, we need to become the wins owner
                 * to force the replication
                 */
-               if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+               if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
                        get_global_id_and_update(&namerec->data.id, True);
                        update_wins_owner(namerec, our_fake_ip);
                        update_wins_flag(namerec, WINS_ACTIVE);
@@ -2138,7 +2138,7 @@ static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA
                }
 
                /* handle records, samba is the wins owner */
-               if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+               if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
                        switch (namerec->data.wins_flags & WINS_STATE_MASK) {
                                case WINS_ACTIVE:
                                        namerec->data.wins_flags&=~WINS_STATE_MASK;
@@ -2424,16 +2424,16 @@ void nmbd_wins_new_entry(struct messaging_context *msg,
                if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
 
                        /* the database record is a replica */
-                       if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+                       if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
                                if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
-                                       if (ip_equal(namerec->data.wins_ip, record->wins_ip))
+                                       if (ip_equal_v4(namerec->data.wins_ip, record->wins_ip))
                                                overwrite=True;
                                } else
                                        overwrite=True;
                        } else {
                        /* we are the wins owner of the database record */
                                /* the 2 records have the same IP address */
-                               if (ip_equal(namerec->data.ip[0], record->ip[0])) {
+                               if (ip_equal_v4(namerec->data.ip[0], record->ip[0])) {
                                        if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
                                                get_global_id_and_update(&namerec->data.id, True);
                                        else
@@ -2485,10 +2485,10 @@ void nmbd_wins_new_entry(struct messaging_context *msg,
                                        overwrite=True;
                        }
                        else {
-                               if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+                               if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
                                        overwrite=True;
                                
-                               if (ip_equal(namerec->data.wins_ip, our_fake_ip))
+                               if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip))
                                        if (namerec->data.wins_flags&WINS_UNIQUE)
                                                get_global_id_and_update(&namerec->data.id, True);
                                
@@ -2497,7 +2497,7 @@ void nmbd_wins_new_entry(struct messaging_context *msg,
                        if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
                                if (namerec->data.wins_flags&WINS_UNIQUE ||
                                    namerec->data.wins_flags&WINS_MHOMED)
-                                       if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+                                       if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
                                                overwrite=True;
                                
                }
index dc2664b67c21cf7b1170eae8a93c8ce117e43fb9..eef57ca2c0d20a378e5325665442f354dc754c30 100644 (file)
@@ -90,8 +90,10 @@ static const char *family_name(int family)
                        return "AF_UNSPEC";
                case AF_INET:
                        return "AF_INET";
+#if defined(HAVE_IPv6)
                case AF_INET6:
                        return "AF_INET6";
+#endif
                default:
                        break;
        }
@@ -135,8 +137,10 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc,
                case AF_UNSPEC:
                case AF_INET:
                        break;
+#if defined(HAVE_IPv6)
                case AF_INET6: /* not yet */
                        return KRB5_PLUGIN_NO_HANDLE;
+#endif
                default:
                        return EINVAL;
        }
index 38bf3259f4f029882d3f8771dbecff4b3630b7fe..3401918f59c21617681f219269dbba1e86e990d6 100644 (file)
@@ -108,7 +108,11 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
                        free( address );
                        return NULL;
                }
-               *ret = address[0].ip;
+               if (address[0].ss.ss_family != AF_INET) {
+                       free(address);
+                       return NULL;
+               }
+               *ret = ((struct sockaddr_in *)&address[0].ss)->sin_addr;
                free( address );
                return ret;
        }
@@ -121,11 +125,17 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
        /* uggh, we have to broadcast to each interface in turn */
        for (j=iface_count() - 1;j >= 0;j--) {
                const struct in_addr *bcast = iface_n_bcast_v4(j);
+               struct sockaddr_storage ss;
+               struct sockaddr_storage *pss;
                if (!bcast) {
                        continue;
                }
-               ret = name_query(fd,name,0x00,True,True,*bcast,count, &flags, NULL);
-               if (ret) break;
+               in_addr_to_sockaddr_storage(&ss, *bcast);
+               pss = name_query(fd,name,0x00,True,True,&ss,count, &flags, NULL);
+               if (pss) {
+                       *ret = ((struct sockaddr_in *)pss)->sin_addr;
+                       break;
+               }
        }
 
        close(fd);
index b651fdaac320e175ff90fc2acfbb9f90316315dd..13c0f38b74d47d12ac4bf5ba5ce9c7e842df8820 100644 (file)
@@ -90,7 +90,7 @@ NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_C
         uint32 logon_attempts = 0x0;
         uint32 tc_status;
        fstring servername, domain, dc_name, dc_name2;
-       struct in_addr dc_ip;
+       struct sockaddr_storage dc_ss;
 
        /* this should be \\global_myname() */
        unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername));
@@ -107,7 +107,7 @@ NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_C
                        if ( !is_trusted_domain( domain ) )
                                break;
                                
-                       if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) {
+                       if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) {
                                tc_status = ERROR_NO_LOGON_SERVERS;
                                break;
                        }
@@ -124,7 +124,7 @@ NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_C
                        if ( !is_trusted_domain( domain ) )
                                break;
                                
-                       if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) {
+                       if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) {
                                tc_status = ERROR_NO_LOGON_SERVERS;
                                break;
                        }
index 658ed994002134f0c268ae70b3eb6ab1e5a0b263..aba56c2d05e5c9cc1f771ca86861935289387aa4 100644 (file)
@@ -2528,26 +2528,28 @@ done:
 **********************************************************/
 
 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
-                       struct in_addr *client_ip, const char *remote_machine)
+                       struct sockaddr_storage *client_ss, const char *remote_machine)
 {
        NTSTATUS ret;
        struct cli_state *the_cli;
-       struct in_addr rm_addr;
+       struct sockaddr_storage rm_addr;
 
-       if ( is_zero_ip_v4(*client_ip) ) {
+       if ( is_zero_addr(client_ss) ) {
                if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
                        DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
                        return False;
                }
 
-               if ( ismyip_v4( rm_addr )) {
+               if (ismyaddr(&rm_addr)) {
                        DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
                        return False;
                }
        } else {
-               rm_addr.s_addr = client_ip->s_addr;
+               char addr[INET6_ADDRSTRLEN];
+               rm_addr = *client_ss;
+               print_sockaddr(addr, sizeof(addr), &rm_addr);
                DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
-                       inet_ntoa(*client_ip) ));
+                       addr));
        }
 
        /* setup the connection */
@@ -2596,7 +2598,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
 
 static bool srv_spoolss_replyopenprinter(int snum, const char *printer, 
                                        uint32 localprinter, uint32 type, 
-                                       POLICY_HND *handle, struct in_addr *client_ip)
+                                       POLICY_HND *handle, struct sockaddr_storage *client_ss)
 {
        WERROR result;
 
@@ -2609,7 +2611,7 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
 
                fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
 
-               if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ip, unix_printer ))
+               if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
                        return False;
                        
                messaging_register(smbd_messaging_context(), NULL,
@@ -2660,7 +2662,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
        uint32 printerlocal = q_u->printerlocal;
        int snum = -1;
        SPOOL_NOTIFY_OPTION *option = q_u->option;
-       struct in_addr client_ip;
+       struct sockaddr_storage client_ss;
 
        /* store the notify value in the printer struct */
 
@@ -2690,12 +2692,16 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
        else if ( (Printer->printer_type == SPLHND_PRINTER) &&
                        !get_printer_snum(p, handle, &snum, NULL) )
                return WERR_BADFID;
-               
-       client_ip.s_addr = inet_addr(p->conn->client_address);
+
+       if (!interpret_string_addr(&client_ss,
+                               p->conn->client_address,
+                               AI_NUMERICHOST)) {
+               return WERR_SERVER_UNAVAILABLE;
+       }
 
        if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
                                        Printer->notify.printerlocal, 1,
-                                       &Printer->notify.client_hnd, &client_ip))
+                                       &Printer->notify.client_hnd, &client_ss))
                return WERR_SERVER_UNAVAILABLE;
 
        Printer->notify.client_connected=True;
index 27b2515169f50be063216fbab5358e16a551de3d..2c285704dedc32e0300c08b901f4179dcca93217 100644 (file)
@@ -709,7 +709,7 @@ out_free:
         * enough to release it -- we don't free the
         * individual strings.  rtfm. */
        free(argv);
-       
+
        return result;
 }
 
@@ -724,7 +724,7 @@ out_free:
        struct cli_state        *cli;
        static char             *opt_ipaddr=NULL;
        struct cmd_set          **cmd_set;
-       struct in_addr          server_ip;
+       struct sockaddr_storage server_ss;
        NTSTATUS                nt_status;
        static int              opt_port = 0;
        fstring new_workgroup;
@@ -745,14 +745,14 @@ out_free:
 
        load_case_tables();
 
-       ZERO_STRUCT(server_ip);
+       zero_addr(&server_ss, AF_INET);
 
        setlinebuf(stdout);
 
        /* the following functions are part of the Samba debugging
           facilities.  See lib/debug.c */
        setup_logging("rpcclient", True);
-       
+
        /* Parse options */
 
        pc = poptGetContext("rpcclient", argc, (const char **) argv,
@@ -762,12 +762,14 @@ out_free:
                poptPrintHelp(pc, stderr, 0);
                return 0;
        }
-       
+
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
 
                case 'I':
-                       if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) {
+                       if (!interpret_string_addr(&server_ss,
+                                               opt_ipaddr,
+                                               AI_NUMERICHOST)) {
                                fprintf(stderr, "%s not a valid IP address\n",
                                        opt_ipaddr);
                                return 1;
@@ -779,7 +781,7 @@ out_free:
           than one unparsed argument is present. */
 
        server = poptGetArg(pc);
-       
+
        if (!server || poptGetArg(pc)) {
                poptPrintHelp(pc, stderr, 0);
                return 1;
@@ -793,11 +795,11 @@ out_free:
                return 1;
 
        /* save the workgroup...
-       
-          FIXME!! do we need to do this for other options as well 
-          (or maybe a generic way to keep lp_load() from overwriting 
+
+          FIXME!! do we need to do this for other options as well
+          (or maybe a generic way to keep lp_load() from overwriting
           everything)?  */
-       
+
        fstrcpy( new_workgroup, lp_workgroup() );
 
        /* Load smb.conf file */
@@ -819,21 +821,21 @@ out_free:
                        pstrcpy(cmdline_auth_info.password, pass);
                }
        }
-       
+
        if ((server[0] == '/' && server[1] == '/') ||
                        (server[0] == '\\' && server[1] ==  '\\')) {
                server += 2;
        }
 
-       nt_status = cli_full_connection(&cli, global_myname(), server, 
-                                       opt_ipaddr ? &server_ip : NULL, opt_port,
-                                       "IPC$", "IPC",  
-                                       cmdline_auth_info.username, 
+       nt_status = cli_full_connection(&cli, global_myname(), server,
+                                       opt_ipaddr ? &server_ss : NULL, opt_port,
+                                       "IPC$", "IPC",
+                                       cmdline_auth_info.username,
                                        lp_workgroup(),
-                                       cmdline_auth_info.password, 
+                                       cmdline_auth_info.password,
                                        cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
                                        cmdline_auth_info.signing_state,NULL);
-       
+
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
                return 1;
@@ -856,19 +858,19 @@ out_free:
        }
 
        fetch_machine_sid(cli);
+
        /* Do anything specified with -c */
         if (cmdstr && cmdstr[0]) {
                 char    *cmd;
                 char    *p = cmdstr;
                int result = 0;
+
                 while((cmd=next_command(&p)) != NULL) {
                         NTSTATUS cmd_result = process_cmd(cli, cmd);
                        SAFE_FREE(cmd);
                        result = NT_STATUS_IS_ERR(cmd_result);
                 }
-               
+
                cli_shutdown(cli);
                 return result;
         }
@@ -889,7 +891,7 @@ out_free:
                if (line[0] != '\n')
                        process_cmd(cli, line);
        }
-       
+
        cli_shutdown(cli);
        return 0;
 }
index eb26e56ac54005a48b512c1b91d0ddca516c6779..8ed0975781cab13e7cd21b0bed70d1fb0551ac2c 100644 (file)
@@ -30,7 +30,7 @@
 NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       struct in_addr pdc_ip;
+       struct sockaddr_storage pdc_ss;
        fstring dc_name;
        struct cli_state *cli = NULL;
        struct rpc_pipe_client *netlogon_pipe = NULL;
@@ -41,12 +41,12 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
        if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
                /* Use the PDC *only* for this */
        
-               if ( !get_pdc_ip(domain, &pdc_ip) ) {
+               if ( !get_pdc_ip(domain, &pdc_ss) ) {
                        DEBUG(0,("Can't get IP for PDC for domain %s\n", domain));
                        goto failed;
                }
 
-               if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
+               if ( !name_status_find( domain, 0x1b, 0x20, &pdc_ss, dc_name) )
                        goto failed;
        } else {
                /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
index e52c2b3fba47ab177e28a25e5b6933977b7217af..61e20ce2740d62428eddf12848baeedf3c10ed50 100644 (file)
@@ -311,7 +311,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                return open_sockets_inetd();
        }
 
-               
 #ifdef HAVE_ATEXIT
        {
                static int atexit_set;
@@ -324,7 +323,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
        /* Stop zombies */
        CatchSignal(SIGCLD, sig_cld);
-                               
+
        FD_ZERO(&listen_set);
 
        /* use a reasonable default set of ports - listing on 445 and 139 */
@@ -340,50 +339,50 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
        }
 
        if (lp_interfaces() && lp_bind_interfaces_only()) {
-               /* We have been given an interfaces line, and been 
+               /* We have been given an interfaces line, and been
                   told to only bind to those interfaces. Create a
                   socket per interface and bind to only these.
                */
-               
+
                /* Now open a listen socket for each of the
                   interfaces. */
                for(i = 0; i < num_interfaces; i++) {
                        const struct sockaddr_storage *ifss =
                                        iface_n_sockaddr_storage(i);
-                       const struct in_addr *ifip;
                        fstring tok;
                        const char *ptr;
 
                        if (ifss == NULL) {
-                               DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+                               DEBUG(0,("open_sockets_smbd: "
+                                       "interface %d has NULL IP address !\n",
+                                       i));
                                continue;
                        }
 
-                       /* For now only deal with IPv4. */
-                       if (ifss->ss_family != AF_INET) {
-                               continue;
-                       }
-
-                       ifip = &((const struct sockaddr_in *)ifss)->sin_addr;
-
-                       for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+                       for (ptr=ports; next_token(&ptr, tok, " \t,",
+                                               sizeof(tok)); ) {
                                unsigned port = atoi(tok);
                                if (port == 0 || port > 0xffff) {
                                        continue;
                                }
-                               s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
-                               if(s == -1)
-                                       return False;
+                               s = fd_listenset[num_sockets] =
+                                       open_socket_in(SOCK_STREAM, port, 0,
+                                                       ifss, True);
+                               if(s == -1) {
+                                       return false;
+                               }
 
                                /* ready to listen */
-                               set_socket_options(s,"SO_KEEPALIVE"); 
+                               set_socket_options(s,"SO_KEEPALIVE");
                                set_socket_options(s,user_socket_options);
-     
-                               /* Set server socket to non-blocking for the accept. */
-                               set_blocking(s,False); 
+
+                               /* Set server socket to
+                                * non-blocking for the accept. */
+                               set_blocking(s,False);
+
                                if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
-                                       DEBUG(0,("listen: %s\n",strerror(errno)));
+                                       DEBUG(0,("open_sockets_smbd: listen: "
+                                               "%s\n", strerror(errno)));
                                        close(s);
                                        return False;
                                }
@@ -392,7 +391,8 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                                num_sockets++;
                                if (num_sockets >= FD_SETSIZE) {
-                                       DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
+                                       DEBUG(0,("open_sockets_smbd: Too "
+                                               "many sockets to bind to\n"));
                                        return False;
                                }
                        }
@@ -403,44 +403,71 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                fstring tok;
                const char *ptr;
+               const char *sock_addr = lp_socket_address();
+               fstring sock_tok;
+               const char *sock_ptr;
+
+               if (strequal(sock_addr, "0.0.0.0") ||
+                               strequal(sock_addr, "::")) {
+#if HAVE_IPV6
+                       sock_addr = "::,0.0.0.0";
+#else
+                       sock_addr = "0.0.0.0";
+#endif
+               }
 
-               num_interfaces = 1;
-               
-               for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
-                       unsigned port = atoi(tok);
-                       if (port == 0 || port > 0xffff) continue;
-                       /* open an incoming socket */
-                       s = open_socket_in(SOCK_STREAM, port, 0,
-                                          interpret_addr(lp_socket_address()),True);
-                       if (s == -1)
-                               return(False);
-               
-                       /* ready to listen */
-                       set_socket_options(s,"SO_KEEPALIVE"); 
-                       set_socket_options(s,user_socket_options);
-                       
-                       /* Set server socket to non-blocking for the accept. */
-                       set_blocking(s,False); 
-                       if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
-                               DEBUG(0,("open_sockets_smbd: listen: %s\n",
-                                        strerror(errno)));
-                               close(s);
-                               return False;
-                       }
+               for (sock_ptr=sock_addr; next_token(&sock_ptr, sock_tok, " \t,",
+                                       sizeof(sock_tok)); ) {
+                       for (ptr=ports; next_token(&ptr, tok, " \t,",
+                                               sizeof(tok)); ) {
+                               struct sockaddr_storage ss;
+
+                               unsigned port = atoi(tok);
+                               if (port == 0 || port > 0xffff) {
+                                       continue;
+                               }
+                               /* open an incoming socket */
+                               if (!interpret_string_addr(&ss, sock_tok,
+                                               AI_NUMERICHOST|AI_PASSIVE)) {
+                                       return false;
+                               }
 
-                       fd_listenset[num_sockets] = s;
-                       FD_SET(s,&listen_set);
-                       maxfd = MAX( maxfd, s);
+                               s = open_socket_in(SOCK_STREAM, port, 0,
+                                                  &ss, true);
+                               if (s == -1) {
+                                       return false;
+                               }
+
+                               /* ready to listen */
+                               set_socket_options(s,"SO_KEEPALIVE");
+                               set_socket_options(s,user_socket_options);
 
-                       num_sockets++;
+                               /* Set server socket to non-blocking
+                                * for the accept. */
+                               set_blocking(s,False);
 
-                       if (num_sockets >= FD_SETSIZE) {
-                               DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
-                               return False;
+                               if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
+                                       DEBUG(0,("open_sockets_smbd: "
+                                               "listen: %s\n",
+                                                strerror(errno)));
+                                       close(s);
+                                       return False;
+                               }
+
+                               fd_listenset[num_sockets] = s;
+                               FD_SET(s,&listen_set);
+