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);
+                               maxfd = MAX( maxfd, s);
+
+                               num_sockets++;
+
+                               if (num_sockets >= FD_SETSIZE) {
+                                       DEBUG(0,("open_sockets_smbd: Too "
+                                               "many sockets to bind to\n"));
+                                       return False;
+                               }
                        }
                }
-       } 
+       }
 
        SAFE_FREE(ports);
 
@@ -461,7 +488,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
        messaging_register(smbd_messaging_context(), NULL,
                           MSG_SMB_FILE_RENAME, msg_file_was_renamed);
        messaging_register(smbd_messaging_context(), NULL,
-                          MSG_SMB_CONF_UPDATED, smb_conf_updated); 
+                          MSG_SMB_CONF_UPDATED, smb_conf_updated);
        messaging_register(smbd_messaging_context(), NULL,
                           MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete);
        brl_register_msgs(smbd_messaging_context());
@@ -478,7 +505,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                struct timeval now, idle_timeout;
                fd_set r_fds, w_fds;
                int num;
-               
+
                /* Ensure we respond to PING and DEBUG messages from the main smbd. */
                message_dispatch(smbd_messaging_context());
 
@@ -493,7 +520,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                idle_timeout = timeval_zero();
 
-               memcpy((char *)&r_fds, (char *)&listen_set, 
+               memcpy((char *)&r_fds, (char *)&listen_set,
                       sizeof(listen_set));
                FD_ZERO(&w_fds);
                GetTimeOfDay(&now);
@@ -521,7 +548,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                        continue;
                }
-               
+
                if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
                        continue;
                }
@@ -548,10 +575,10 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                        }
 
                        smbd_set_server_fd(accept(s,&addr,&in_addrlen));
-                       
+
                        if (smbd_server_fd() == -1 && errno == EINTR)
                                continue;
-                       
+
                        if (smbd_server_fd() == -1) {
                                DEBUG(0,("open_sockets_smbd: accept: %s\n",
                                         strerror(errno)));
@@ -563,7 +590,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                        if (smbd_server_fd() != -1 && interactive)
                                return True;
-                       
+
                        if (allowable_number_of_smbd_processes() &&
                            smbd_server_fd() != -1 &&
                            ((child = sys_fork())==0)) {
@@ -572,24 +599,24 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                /* Stop zombies, the parent explicitly handles
                                 * them, counting worker smbds. */
                                CatchChild();
-                               
+
                                /* close the listening socket(s) */
                                for(i = 0; i < num_sockets; i++)
                                        close(fd_listenset[i]);
-                               
+
                                /* close our standard file
                                   descriptors */
                                close_low_fds(False);
                                am_parent = 0;
-                               
+
                                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
                                set_socket_options(smbd_server_fd(),user_socket_options);
-                               
+
                                /* this is needed so that we get decent entries
                                   in smbstatus for port 445 connects */
                                set_remote_machine_name(get_peer_addr(smbd_server_fd()),
                                                        False);
-                               
+
                                /* Reset the state of the random
                                 * number generation system, so
                                 * children do not get the same random
@@ -603,10 +630,10 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                        smb_panic("tdb_reopen_all failed");
                                }
 
-                               return True; 
+                               return True;
                        }
                        /* The parent doesn't need this socket */
-                       close(smbd_server_fd()); 
+                       close(smbd_server_fd());
 
                        /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
                                Clear the closed fd info out of server_fd --
@@ -637,7 +664,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                         * (ca. 100kb).
                         * */
                        force_check_log_size();
+
                } /* end for num */
        } /* end while 1 */
 
index 20fd49b3e1010e898495cd8d11bbbafc732b842c..f69f8bf48f300e7f917d50bf543c239b95e11052 100644 (file)
@@ -161,7 +161,7 @@ static struct cli_state *connect_one(char *share, int snum)
        struct nmb_name called, calling;
        char *server_n;
        fstring server;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        fstring myname;
        static int count;
        NTSTATUS status;
@@ -173,8 +173,8 @@ static struct cli_state *connect_one(char *share, int snum)
        share++;
 
        server_n = server;
-       
-        zero_ip_v4(&ip);
+
+       zero_addr(&ss, AF_INET);
 
        slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
 
@@ -182,7 +182,7 @@ static struct cli_state *connect_one(char *share, int snum)
        make_nmb_name(&called , server, 0x20);
 
  again:
-        zero_ip_v4(&ip);
+        zero_addr(&ss, AF_INET);
 
        /* have to open a new connection */
        if (!(c=cli_initialise())) {
@@ -190,7 +190,7 @@ static struct cli_state *connect_one(char *share, int snum)
                return NULL;
        }
 
-       status = cli_connect(c, server_n, &ip);
+       status = cli_connect(c, server_n, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
                return NULL;
index 84c6e1c3a4b81f0b4c9e58f8263eb9c97b885f0a..354607bb4e5fa39db94614091beda5f9f3fa98ce 100644 (file)
@@ -168,7 +168,7 @@ static struct cli_state *connect_one(char *share)
        struct nmb_name called, calling;
        char *server_n;
        char *server;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        NTSTATUS status;
 
        server = share+2;
@@ -178,14 +178,14 @@ static struct cli_state *connect_one(char *share)
        share++;
 
        server_n = server;
-       
-        zero_ip_v4(&ip);
+
+       zero_addr(&ss, AF_INET);
 
        make_nmb_name(&calling, "masktest", 0x0);
        make_nmb_name(&called , server, 0x20);
 
  again:
-        zero_ip_v4(&ip);
+        zero_addr(&ss, AF_INET);
 
        /* have to open a new connection */
        if (!(c=cli_initialise())) {
@@ -193,7 +193,7 @@ static struct cli_state *connect_one(char *share)
                return NULL;
        }
 
-       status = cli_connect(c, server_n, &ip);
+       status = cli_connect(c, server_n, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
                return NULL;
index d68421623294780d15c8907af1ff7eab722e0474..8eb29d837da9ba638476491180272e44f6a8f3b5 100644 (file)
@@ -99,14 +99,14 @@ void *shm_setup(int size)
 static struct cli_state *open_nbt_connection(void)
 {
        struct nmb_name called, calling;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        struct cli_state *c;
        NTSTATUS status;
 
        make_nmb_name(&calling, myname, 0x0);
        make_nmb_name(&called , host, 0x20);
 
-        zero_ip_v4(&ip);
+        zero_addr(&ss, AF_INET);
 
        if (!(c = cli_initialise())) {
                printf("Failed initialize cli_struct to connect with %s\n", host);
@@ -115,7 +115,7 @@ static struct cli_state *open_nbt_connection(void)
 
        c->port = port_to_use;
 
-       status = cli_connect(c, host, &ip);
+       status = cli_connect(c, host, &ss);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
                return NULL;
@@ -129,10 +129,10 @@ static struct cli_state *open_nbt_connection(void)
 
        if (!cli_session_request(c, &calling, &called)) {
                /*
-                * Well, that failed, try *SMBSERVER ... 
+                * Well, that failed, try *SMBSERVER ...
                 * However, we must reconnect as well ...
                 */
-               status = cli_connect(c, host, &ip);
+               status = cli_connect(c, host, &ss);
                if (!NT_STATUS_IS_OK(status)) {
                        printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
                        return NULL;
index 068118f476f56a7eef71ef9be4e6a7ef8d4f43bb..fb82e7659112fdef0983769dd0eb15eadc374291 100644 (file)
@@ -56,7 +56,7 @@
 
 /* Yes, these buggers are globals.... */
 const char *opt_requester_name = NULL;
-const char *opt_host = NULL; 
+const char *opt_host = NULL;
 const char *opt_password = NULL;
 const char *opt_user_name = NULL;
 bool opt_user_specified = False;
@@ -87,7 +87,7 @@ const char *opt_destination = NULL;
 int opt_testmode = False;
 
 int opt_have_ip = False;
-struct in_addr opt_dest_ip;
+struct sockaddr_storage opt_dest_ip;
 
 extern bool AllowDebugChange;
 
@@ -157,12 +157,13 @@ int net_run_function2(int argc, const char **argv, const char *whoami,
 }
 
 /****************************************************************************
-connect to \\server\service 
+ Connect to \\server\service.
 ****************************************************************************/
 
-NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
-                                       const char *server_name, 
-                                       const char *service_name, 
+NTSTATUS connect_to_service(struct cli_state **c,
+                                       struct sockaddr_storage *server_ss,
+                                       const char *server_name,
+                                       const char *service_name,
                                        const char *service_type)
 {
        NTSTATUS nt_status;
@@ -172,9 +173,9 @@ NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
                return NT_STATUS_NO_MEMORY;
        }
 
-       nt_status = cli_full_connection(c, NULL, server_name, 
-                                       server_ip, opt_port,
-                                       service_name, service_type,  
+       nt_status = cli_full_connection(c, NULL, server_name,
+                                       server_ss, opt_port,
+                                       service_name, service_type,
                                        opt_user_name, opt_workgroup,
                                        opt_password, 0, Undefined, NULL);
        if (NT_STATUS_IS_OK(nt_status)) {
@@ -184,15 +185,15 @@ NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
 
                /* Display a nicer message depending on the result */
 
-               if (NT_STATUS_V(nt_status) == 
+               if (NT_STATUS_V(nt_status) ==
                    NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
                        d_fprintf(stderr, "The username or password was not correct.\n");
 
-               if (NT_STATUS_V(nt_status) == 
+               if (NT_STATUS_V(nt_status) ==
                    NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
                        d_fprintf(stderr, "The account was locked out.\n");
 
-               if (NT_STATUS_V(nt_status) == 
+               if (NT_STATUS_V(nt_status) ==
                    NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
                        d_fprintf(stderr, "The account was disabled.\n");
 
@@ -200,30 +201,33 @@ NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
        }
 }
 
-
 /****************************************************************************
-connect to \\server\ipc$  
+ Connect to \\server\ipc$.
 ****************************************************************************/
-NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
-                                       const char *server_name)
+
+NTSTATUS connect_to_ipc(struct cli_state **c,
+                       struct sockaddr_storage *server_ss,
+                       const char *server_name)
 {
-       return connect_to_service(c, server_ip, server_name, "IPC$", "IPC");
+       return connect_to_service(c, server_ss, server_name, "IPC$", "IPC");
 }
 
 /****************************************************************************
-connect to \\server\ipc$ anonymously
+ Connect to \\server\ipc$ anonymously.
 ****************************************************************************/
+
 NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
-                       struct in_addr *server_ip, const char *server_name)
+                               struct sockaddr_storage *server_ss,
+                               const char *server_name)
 {
        NTSTATUS nt_status;
 
-       nt_status = cli_full_connection(c, opt_requester_name, server_name, 
-                                       server_ip, opt_port,
-                                       "IPC$", "IPC",  
+       nt_status = cli_full_connection(c, opt_requester_name, server_name,
+                                       server_ss, opt_port,
+                                       "IPC$", "IPC",
                                        "", "",
                                        "", 0, Undefined, NULL);
-       
+
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        } else {
@@ -254,11 +258,12 @@ static char *get_user_and_realm(const char *username)
 }
 
 /****************************************************************************
-connect to \\server\ipc$ using KRB5
+ Connect to \\server\ipc$ using KRB5.
 ****************************************************************************/
 
 NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
-                       struct in_addr *server_ip, const char *server_name)
+                       struct sockaddr_storage *server_ss,
+                       const char *server_name)
 {
        NTSTATUS nt_status;
        char *user_and_realm = NULL;
@@ -273,13 +278,13 @@ NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
                return NT_STATUS_NO_MEMORY;
        }
 
-       nt_status = cli_full_connection(c, NULL, server_name, 
-                                       server_ip, opt_port,
-                                       "IPC$", "IPC",  
+       nt_status = cli_full_connection(c, NULL, server_name,
+                                       server_ss, opt_port,
+                                       "IPC$", "IPC",
                                        user_and_realm, opt_workgroup,
                                        opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, 
                                        Undefined, NULL);
-       
+
        SAFE_FREE(user_and_realm);
 
        if (NT_STATUS_IS_OK(nt_status)) {
@@ -367,7 +372,7 @@ int net_use_krb_machine_account(void)
 int net_use_machine_account(void)
 {
        char *user_name = NULL;
-               
+
        if (!secrets_init()) {
                d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
                exit(1);
@@ -381,62 +386,78 @@ int net_use_machine_account(void)
        return 0;
 }
 
-bool net_find_server(const char *domain, unsigned flags, struct in_addr *server_ip, char **server_name)
+bool net_find_server(const char *domain,
+                       unsigned flags,
+                       struct sockaddr_storage *server_ss,
+                       char **server_name)
 {
        const char *d = domain ? domain : opt_target_workgroup;
 
        if (opt_host) {
                *server_name = SMB_STRDUP(opt_host);
-       }               
+       }
 
        if (opt_have_ip) {
-               *server_ip = opt_dest_ip;
+               *server_ss = opt_dest_ip;
                if (!*server_name) {
-                       *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr), &opt_dest_ip);
+                       *server_name = SMB_STRDUP(addr);
                }
        } else if (*server_name) {
                /* resolve the IP address */
-               if (!resolve_name(*server_name, server_ip, 0x20))  {
+               if (!resolve_name(*server_name, server_ss, 0x20))  {
                        DEBUG(1,("Unable to resolve server name\n"));
-                       return False;
+                       return false;
                }
        } else if (flags & NET_FLAGS_PDC) {
-               struct in_addr pdc_ip;
-
-               if (get_pdc_ip(d, &pdc_ip)) {
-                       fstring dc_name;
-                       
-                       if (is_zero_ip_v4(pdc_ip))
-                               return False;
-                       
-                       if ( !name_status_find(d, 0x1b, 0x20, pdc_ip, dc_name) )
-                               return False;
-                               
-                       *server_name = SMB_STRDUP(dc_name);
-                       *server_ip = pdc_ip;
+               fstring dc_name;
+               struct sockaddr_storage pdc_ss;
+
+               if (get_pdc_ip(d, &pdc_ss)) {
+                       DEBUG(1,("Unable to resolve PDC server address\n"));
+                       return false;
+               }
+
+               if (is_zero_addr(&pdc_ss)) {
+                       return false;
                }
+
+               if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
+                       return False;
+               }
+
+               *server_name = SMB_STRDUP(dc_name);
+               *server_ss = pdc_ss;
        } else if (flags & NET_FLAGS_DMB) {
-               struct in_addr msbrow_ip;
+               struct sockaddr_storage msbrow_ss;
+               char addr[INET6_ADDRSTRLEN];
+
                /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
-               if (!resolve_name(d, &msbrow_ip, 0x1B))  {
+               if (!resolve_name(d, &msbrow_ss, 0x1B))  {
                        DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
-                       return False;
-               } else {
-                       *server_ip = msbrow_ip;
+                       return false;
                }
-               *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+               *server_ss = msbrow_ss;
+               print_sockaddr(addr, sizeof(addr), server_ss);
+               *server_name = SMB_STRDUP(addr);
        } else if (flags & NET_FLAGS_MASTER) {
-               struct in_addr brow_ips;
-               if (!resolve_name(d, &brow_ips, 0x1D))  {
+               struct sockaddr_storage brow_ss;
+               char addr[INET6_ADDRSTRLEN];
+               if (!resolve_name(d, &brow_ss, 0x1D))  {
                                /* go looking for workgroups */
                        DEBUG(1,("Unable to resolve master browser via name lookup\n"));
-                       return False;
-               } else {
-                       *server_ip = brow_ips;
+                       return false;
                }
-               *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+               *server_ss = brow_ss;
+               print_sockaddr(addr, sizeof(addr), server_ss);
+               *server_name = SMB_STRDUP(addr);
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
-               (*server_ip).s_addr = htonl(INADDR_LOOPBACK);
+               if (!interpret_string_addr(server_ss,
+                                       "127.0.0.1", AI_NUMERICHOST)) {
+                       DEBUG(1,("Unable to resolve 127.0.0.1\n"));
+                       return false;
+               }
                *server_name = SMB_STRDUP("127.0.0.1");
        }
 
@@ -448,20 +469,22 @@ bool net_find_server(const char *domain, unsigned flags, struct in_addr *server_
        return True;
 }
 
-
-bool net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
+bool net_find_pdc(struct sockaddr_storage *server_ss,
+               fstring server_name,
+               const char *domain_name)
 {
-       if (get_pdc_ip(domain_name, server_ip)) {
-               if (is_zero_ip_v4(*server_ip))
-                       return False;
-               
-               if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
-                       return False;
-                       
-               return True;    
-       } 
-       else
-               return False;
+       if (!get_pdc_ip(domain_name, server_ss)) {
+               return false;
+       }
+       if (is_zero_addr(server_ss)) {
+               return false;
+       }
+
+       if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
+               return false;
+       }
+
+       return true;
 }
 
 NTSTATUS net_make_ipc_connection(unsigned flags, struct cli_state **pcli)
@@ -470,29 +493,29 @@ NTSTATUS net_make_ipc_connection(unsigned flags, struct cli_state **pcli)
 }
 
 NTSTATUS net_make_ipc_connection_ex(const char *domain, const char *server,
-                                    struct in_addr *ip, unsigned flags,
+                                    struct sockaddr_storage *pss, unsigned flags,
                                    struct cli_state **pcli)
 {
        char *server_name = NULL;
-       struct in_addr server_ip;
+       struct sockaddr_storage server_ss;
        struct cli_state *cli = NULL;
        NTSTATUS nt_status;
 
-       if ( !server || !ip ) {
-               if (!net_find_server(domain, flags, &server_ip, &server_name)) {
+       if ( !server || !pss ) {
+               if (!net_find_server(domain, flags, &server_ss, &server_name)) {
                        d_fprintf(stderr, "Unable to find a suitable server\n");
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
                }
        } else {
                server_name = SMB_STRDUP( server );
-               server_ip = *ip;
+               server_ss = *pss;
        }
 
        if (flags & NET_FLAGS_ANONYMOUS) {
-               nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name);
+               nt_status = connect_to_ipc_anonymous(&cli, &server_ss, server_name);
        } else {
-               nt_status = connect_to_ipc(&cli, &server_ip, server_name);
+               nt_status = connect_to_ipc(&cli, &server_ss, server_name);
        }
 
        /* store the server in the affinity cache if it was a PDC */
@@ -989,7 +1012,7 @@ static struct functable net_func[] = {
 
        TALLOC_CTX *frame = talloc_stackframe();
 
-       zero_ip_v4(&opt_dest_ip);
+       zero_addr(&opt_dest_ip, AF_INET);
 
        load_case_tables();
 
@@ -1007,11 +1030,12 @@ static struct functable net_func[] = {
                        exit(0);
                        break;
                case 'I':
-                       opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
-                       if (is_zero_ip_v4(opt_dest_ip))
+                       if (!interpret_string_addr(&opt_dest_ip,
+                                               poptGetOptArg(pc), 0)) {
                                d_fprintf(stderr, "\nInvalid ip address specified\n");
-                       else
+                       } else {
                                opt_have_ip = True;
+                       }
                        break;
                case 'U':
                        opt_user_specified = True;
index 177c6d360198e981a8a538c88677946b4fb8cdf3..2ffa4d77b199c9bf453576ef511154e03386f4d8 100644 (file)
@@ -114,7 +114,7 @@ extern const char *opt_destination;
 extern int opt_testmode;
 
 extern int opt_have_ip;
-extern struct in_addr opt_dest_ip;
+extern struct sockaddr_storage opt_dest_ip;
 
 extern const char *share_type[];
 
index bfbcbbde49c67866502c72478dfea942d59a22e4..81b13ba76ecece7ba747127eb096e57d66deeb55 100644 (file)
@@ -78,15 +78,17 @@ static const char *assume_own_realm(void)
 */
 static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
 {
+       char addr[INET6_ADDRSTRLEN];
        struct cldap_netlogon_reply reply;
 
-       if ( !ads_cldap_netlogon( inet_ntoa(ads->ldap.ip), ads->server.realm, &reply ) ) {
+       print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+       if ( !ads_cldap_netlogon(addr, ads->server.realm, &reply ) ) {
                d_fprintf(stderr, "CLDAP query failed!\n");
                return -1;
        }
 
        d_printf("Information for Domain Controller: %s\n\n",
-               inet_ntoa(ads->ldap.ip));
+               addr);
 
        d_printf("Response Type: ");
        switch (reply.type) {
@@ -144,7 +146,6 @@ static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
        return 0;
 }
 
-
 /*
   this implements the CLDAP based netlogon lookup requests
   for finding the domain controller of a ADS domain
@@ -171,6 +172,7 @@ static int net_ads_lookup(int argc, const char **argv)
 static int net_ads_info(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
+       char addr[INET6_ADDRSTRLEN];
 
        if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
                d_fprintf(stderr, "Didn't find the ldap server!\n");
@@ -189,7 +191,9 @@ static int net_ads_info(int argc, const char **argv)
                d_fprintf( stderr, "Failed to get server's current time!\n");
        }
 
-       d_printf("LDAP server: %s\n", inet_ntoa(ads->ldap.ip));
+       print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+
+       d_printf("LDAP server: %s\n", addr);
        d_printf("LDAP server name: %s\n", ads->config.ldap_server_name);
        d_printf("Realm: %s\n", ads->config.realm);
        d_printf("Bind Path: %s\n", ads->config.bind_path);
@@ -369,6 +373,7 @@ int net_ads_check(void)
 static int net_ads_workgroup(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
+       char addr[INET6_ADDRSTRLEN];
        struct cldap_netlogon_reply reply;
 
        if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
@@ -381,7 +386,8 @@ static int net_ads_workgroup(int argc, const char **argv)
                ads->ldap.port = 389;
        }
 
-       if ( !ads_cldap_netlogon( inet_ntoa(ads->ldap.ip), ads->server.realm, &reply ) ) {
+       print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+       if ( !ads_cldap_netlogon(addr, ads->server.realm, &reply ) ) {
                d_fprintf(stderr, "CLDAP query failed!\n");
                return -1;
        }
@@ -829,7 +835,7 @@ static int net_ads_leave(int argc, const char **argv)
 
        /* make RPC calls here */
 
-       if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ip,
+       if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ss,
                ads->config.ldap_server_name)) )
        {
                goto done;
@@ -952,14 +958,14 @@ static NTSTATUS check_ads_config( void )
  ********************************************************************/
 
 static NTSTATUS net_join_domain(TALLOC_CTX *ctx, const char *servername,
-                               struct in_addr *ip, char **domain,
+                               struct sockaddr_storage *pss, char **domain,
                                DOM_SID **dom_sid,
                                const char *password)
 {
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
        struct cli_state *cli = NULL;
 
-       ret = connect_to_ipc_krb5(&cli, ip, servername);
+       ret = connect_to_ipc_krb5(&cli, pss, servername);
        if ( !NT_STATUS_IS_OK(ret) ) {
                goto done;
        }
@@ -1475,7 +1481,7 @@ int net_ads_join(int argc, const char **argv)
        const char *create_in_ou = NULL;
        int i;
        fstring dc_name;
-       struct in_addr dcip;
+       struct sockaddr_storage dcss;
        const char *os_name = NULL;
        const char *os_version = NULL;
 
@@ -1487,7 +1493,7 @@ int net_ads_join(int argc, const char **argv)
 
        /* find a DC to initialize the server affinity cache */
 
-       get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcip );
+       get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcss );
 
        status = ads_startup(True, &ads);
        if (!ADS_ERR_OK(status)) {
@@ -1566,7 +1572,7 @@ int net_ads_join(int argc, const char **argv)
        password = talloc_strdup(ctx, tmp_password);
 
        nt_status = net_join_domain(ctx, ads->config.ldap_server_name,
-                                   &ads->ldap.ip, &short_domain_name, &domain_sid, password);
+                                   &ads->ldap.ss, &short_domain_name, &domain_sid, password);
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                DEBUG(1, ("call of net_join_domain failed: %s\n",
                          get_friendly_nt_error_msg(nt_status)));
@@ -1602,7 +1608,7 @@ int net_ads_join(int argc, const char **argv)
        /* Verify that everything is ok */
 
        nt_status = net_rpc_join_ok(short_domain_name,
-                                   ads->config.ldap_server_name, &ads->ldap.ip);
+                                   ads->config.ldap_server_name, &ads->ldap.ss);
        if (!NT_STATUS_IS_OK(nt_status)) {
                d_fprintf(stderr,
                          "Failed to verify membership in domain: %s!\n",
@@ -1929,7 +1935,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
        const char *servername, *printername;
        struct cli_state *cli;
        struct rpc_pipe_client *pipe_hnd;
-       struct in_addr          server_ip;
+       struct sockaddr_storage server_ss;
        NTSTATUS nt_status;
        TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish");
        ADS_MODLIST mods = ads_init_mods(mem_ctx);
@@ -1957,10 +1963,10 @@ static int net_ads_printer_publish(int argc, const char **argv)
 
        /* Get printer data from SPOOLSS */
 
-       resolve_name(servername, &server_ip, 0x20);
+       resolve_name(servername, &server_ss, 0x20);
 
        nt_status = cli_full_connection(&cli, global_myname(), servername,
-                                       &server_ip, 0,
+                                       &server_ss, 0,
                                        "IPC$", "IPC",
                                        opt_user_name, opt_workgroup,
                                        opt_password ? opt_password : "",
index a1e8c1a6edb772e0bd7f804b7d767c63bf8e8ce7..f7af1f2bb3ed305916b2674c5a3ccc5ce6d54307 100644 (file)
@@ -1,5 +1,5 @@
-/* 
-   Samba Unix/Linux SMB client library 
+/*
+   Samba Unix/Linux SMB client library
    net lookup command
    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
 
@@ -7,12 +7,12 @@
    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/>.  */
 
@@ -38,12 +38,13 @@ int net_lookup_usage(int argc, const char **argv)
 /* lookup a hostname giving an IP */
 static int net_lookup_host(int argc, const char **argv)
 {
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        int name_type = 0x20;
+       char addr[INET6_ADDRSTRLEN];
        const char *name = argv[0];
        char *p;
 
-       if (argc == 0) 
+       if (argc == 0)
                return net_lookup_usage(argc, argv);
 
        p = strchr_m(name,'#');
@@ -51,27 +52,37 @@ static int net_lookup_host(int argc, const char **argv)
                *p = '\0';
                sscanf(++p,"%x",&name_type);
        }
-       
-       if (!resolve_name(name, &ip, name_type)) {
-               /* we deliberately use DEBUG() here to send it to stderr 
+
+       if (!resolve_name(name, &ss, name_type)) {
+               /* we deliberately use DEBUG() here to send it to stderr
                   so scripts aren't mucked up */
                DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
                return -1;
        }
 
-       d_printf("%s\n", inet_ntoa(ip));
+       print_sockaddr(addr, sizeof(addr), &ss);
+       d_printf("%s\n", addr);
        return 0;
 }
 
 #ifdef HAVE_ADS
 static void print_ldap_srvlist(struct dns_rr_srv *dclist, int numdcs )
 {
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        int i;
 
        for ( i=0; i<numdcs; i++ ) {
-               if ( resolve_name(dclist[i].hostname, &ip, 0x20) ) {
-                       d_printf("%s:%d\n", inet_ntoa(ip), dclist[i].port); 
+               if (resolve_name(dclist[i].hostname, &ss, 0x20) ) {
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr), &ss);
+#ifdef HAVE_IPV6
+                       if (ss.ss_family == AF_INET6) {
+                               d_printf("[%s]:%d\n", addr, dclist[i].port);
+                       }
+#endif
+                       if (ss.ss_family == AF_INET) {
+                               d_printf("%s:%d\n", addr, dclist[i].port);
+                       }
                }
        }
 }
@@ -81,13 +92,14 @@ static int net_lookup_ldap(int argc, const char **argv)
 {
 #ifdef HAVE_ADS
        const char *domain;
-       struct in_addr addr;
-       struct hostent *hostent;
+       struct sockaddr_storage ss;
        struct dns_rr_srv *dcs = NULL;
        int numdcs = 0;
        char *sitename;
        TALLOC_CTX *ctx;
        NTSTATUS status;
+       int ret;
+       char h_name[HOST_NAME_MAX];
 
        if (argc > 0)
                domain = argv[0];
@@ -113,22 +125,26 @@ static int net_lookup_ldap(int argc, const char **argv)
        }
 
        DEBUG(9, ("Looking up PDC for domain %s\n", domain));
-       if (!get_pdc_ip(domain, &addr)) {
+       if (!get_pdc_ip(domain, &ss)) {
                TALLOC_FREE( ctx );
                SAFE_FREE(sitename);
                return -1;
        }
 
-       hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr),
-                               AF_INET);
-       if (!hostent) {
+       ret = getnameinfo((struct sockaddr *)&ss,
+                       sizeof(struct sockaddr_storage),
+                       h_name, sizeof(h_name),
+                       NULL, 0,
+                       NI_NAMEREQD);
+
+       if (ret) {
                TALLOC_FREE( ctx );
                SAFE_FREE(sitename);
                return -1;
        }
 
-       DEBUG(9, ("Found PDC with DNS name %s\n", hostent->h_name));
-       domain = strchr(hostent->h_name, '.');
+       DEBUG(9, ("Found PDC with DNS name %s\n", h_name));
+       domain = strchr(h_name, '.');
        if (!domain) {
                TALLOC_FREE( ctx );
                SAFE_FREE(sitename);
@@ -158,11 +174,12 @@ static int net_lookup_ldap(int argc, const char **argv)
 static int net_lookup_dc(int argc, const char **argv)
 {
        struct ip_service *ip_list;
-       struct in_addr addr;
+       struct sockaddr_storage ss;
        char *pdc_str = NULL;
        const char *domain = NULL;
        char *sitename = NULL;
        int count, i;
+       char addr[INET6_ADDRSTRLEN];
        bool sec_ads = (lp_security() == SEC_ADS);
 
        if (sec_ads) {
@@ -175,23 +192,25 @@ static int net_lookup_dc(int argc, const char **argv)
                domain=argv[0];
 
        /* first get PDC */
-       if (!get_pdc_ip(domain, &addr))
+       if (!get_pdc_ip(domain, &ss))
                return -1;
 
-       asprintf(&pdc_str, "%s", inet_ntoa(addr));
+       print_sockaddr(addr, sizeof(addr), &ss);
+       asprintf(&pdc_str, "%s", addr);
        d_printf("%s\n", pdc_str);
 
        sitename = sitename_fetch(domain);
-       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename, &ip_list, &count, sec_ads))) {
+       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename,
+                                       &ip_list, &count, sec_ads))) {
                SAFE_FREE(pdc_str);
                SAFE_FREE(sitename);
                return 0;
        }
        SAFE_FREE(sitename);
        for (i=0;i<count;i++) {
-               char *dc_str = inet_ntoa(ip_list[i].ip);
-               if (!strequal(pdc_str, dc_str))
-                       d_printf("%s\n", dc_str);
+               print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+               if (!strequal(pdc_str, addr))
+                       d_printf("%s\n", addr);
        }
        SAFE_FREE(pdc_str);
        return 0;
@@ -199,10 +218,11 @@ static int net_lookup_dc(int argc, const char **argv)
 
 static int net_lookup_pdc(int argc, const char **argv)
 {
-       struct in_addr addr;
+       struct sockaddr_storage ss;
        char *pdc_str = NULL;
        const char *domain;
-       
+       char addr[INET6_ADDRSTRLEN];
+
        if (lp_security() == SEC_ADS) {
                domain = lp_realm();
        } else {
@@ -213,10 +233,11 @@ static int net_lookup_pdc(int argc, const char **argv)
                domain=argv[0];
 
        /* first get PDC */
-       if (!get_pdc_ip(domain, &addr))
+       if (!get_pdc_ip(domain, &ss))
                return -1;
 
-       asprintf(&pdc_str, "%s", inet_ntoa(addr));
+       print_sockaddr(addr, sizeof(addr), &ss);
+       asprintf(&pdc_str, "%s", addr);
        d_printf("%s\n", pdc_str);
        SAFE_FREE(pdc_str);
        return 0;
@@ -225,15 +246,17 @@ static int net_lookup_pdc(int argc, const char **argv)
 
 static int net_lookup_master(int argc, const char **argv)
 {
-       struct in_addr master_ip;
+       struct sockaddr_storage master_ss;
        const char *domain=opt_target_workgroup;
+       char addr[INET6_ADDRSTRLEN];
 
        if (argc > 0)
                domain=argv[0];
 
-       if (!find_master_ip(domain, &master_ip))
+       if (!find_master_ip(domain, &master_ss))
                return -1;
-       d_printf("%s\n", inet_ntoa(master_ip));
+       print_sockaddr(addr, sizeof(addr), &master_ss);
+       d_printf("%s\n", addr);
        return 0;
 }
 
index bf5e4c6b6d8c6fb9e04c60ea7d7e843af309ee9c..5c5bb97bf654b8df00a02f4f705273aaeed52d61 100644 (file)
@@ -3728,7 +3728,7 @@ static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
 
                /* open share source */
                nt_status = connect_to_service(&cp_clistate.cli_share_src,
-                                              &cli->dest_ip, cli->desthost,
+                                              &cli->dest_ss, cli->desthost,
                                               netname, "A:");
                if (!NT_STATUS_IS_OK(nt_status))
                        goto done;
@@ -5590,13 +5590,13 @@ static int rpc_trustdom_del(int argc, const char **argv)
 static int rpc_trustdom_establish(int argc, const char **argv)
 {
        struct cli_state *cli = NULL;
-       struct in_addr server_ip;
+       struct sockaddr_storage server_ss;
        struct rpc_pipe_client *pipe_hnd = NULL;
        POLICY_HND connect_hnd;
        TALLOC_CTX *mem_ctx;
        NTSTATUS nt_status;
        DOM_SID *domain_sid;
-       
+
        char* domain_name;
        char* domain_name_pol;
        char* acct_name;
@@ -5617,7 +5617,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
        /* account name used at first is our domain's name with '$' */
        asprintf(&acct_name, "%s$", lp_workgroup());
        strupper_m(acct_name);
-       
+
        /*
         * opt_workgroup will be used by connection functions further,
         * hence it should be set to remote domain name instead of ours
@@ -5625,17 +5625,17 @@ static int rpc_trustdom_establish(int argc, const char **argv)
        if (opt_workgroup) {
                opt_workgroup = smb_xstrdup(domain_name);
        };
-       
+
        opt_user_name = acct_name;
 
        /* find the domain controller */
-       if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
+       if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
                DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
                return -1;
        }
 
        /* connect to ipc$ as username/password */
-       nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
+       nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
        if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
 
                /* Is it trusting domain account for sure ? */
@@ -5647,12 +5647,12 @@ static int rpc_trustdom_establish(int argc, const char **argv)
        /* store who we connected to */
 
        saf_store( domain_name, pdc_name );
-       
+
        /*
         * Connect to \\server\ipc$ again (this time anonymously)
         */
-       
-       nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
+
+       nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
        
        if (NT_STATUS_IS_ERR(nt_status)) {
                DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
@@ -6316,23 +6316,23 @@ bool net_rpc_check(unsigned flags)
 {
        struct cli_state *cli;
        bool ret = False;
-       struct in_addr server_ip;
+       struct sockaddr_storage server_ss;
        char *server_name = NULL;
        NTSTATUS status;
 
        /* flags (i.e. server type) may depend on command */
-       if (!net_find_server(NULL, flags, &server_ip, &server_name))
+       if (!net_find_server(NULL, flags, &server_ss, &server_name))
                return False;
 
        if ((cli = cli_initialise()) == NULL) {
                return False;
        }
 
-       status = cli_connect(cli, server_name, &server_ip);
+       status = cli_connect(cli, server_name, &server_ss);
        if (!NT_STATUS_IS_OK(status))
                goto done;
-       if (!attempt_netbios_session_request(&cli, global_myname(), 
-                                            server_name, &server_ip))
+       if (!attempt_netbios_session_request(&cli, global_myname(),
+                                            server_name, &server_ss))
                goto done;
        if (!cli_negprot(cli))
                goto done;
index b32fa27284fbdbef21477c98ff49e79f2056e3e5..0c25a5336528229bee7798d49b393d7d0561d37f 100644 (file)
@@ -41,7 +41,7 @@
  *
  **/
 NTSTATUS net_rpc_join_ok(const char *domain, const char *server,
-                        struct in_addr *ip)
+                        struct sockaddr_storage *pss)
 {
        enum security_types sec;
        unsigned int conn_flags = NET_FLAGS_PDC;
@@ -65,7 +65,7 @@ NTSTATUS net_rpc_join_ok(const char *domain, const char *server,
        }
 
        /* Connect to remote machine */
-       ntret = net_make_ipc_connection_ex(domain, server, ip, conn_flags, &cli);
+       ntret = net_make_ipc_connection_ex(domain, server, pss, conn_flags, &cli);
        if (!NT_STATUS_IS_OK(ntret)) {
                return ntret;
        }
@@ -425,7 +425,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
        }
 
        /* double-check, connection from scratch */
-       result = net_rpc_join_ok(domain, cli->desthost, &cli->dest_ip);
+       result = net_rpc_join_ok(domain, cli->desthost, &cli->dest_ss);
        retval = NT_STATUS_IS_OK(result) ? 0 : -1;
 
 done:
index 20821cd2e6945456d8ca6be908f6f6666323f90e..d14caad97564025ad0550456d11b4f445a4f1fc3 100644 (file)
@@ -1689,7 +1689,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i, p;
        uint32 num_printers;
-       uint32 level = 3; 
+       uint32 level = 3;
        pstring printername = "", sharename = "";
        bool got_hnd_src = False;
        bool got_hnd_dst = False;
@@ -1703,7 +1703,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid,
        struct cli_state *cli_share_src = NULL;
        struct cli_state *cli_share_dst = NULL;
        fstring drivername = "";
-       
+
        ZERO_STRUCT(drv_ctr_src);
        ZERO_STRUCT(drv_ctr_dst);
        ZERO_STRUCT(info_ctr_enum);
@@ -1715,21 +1715,20 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid,
        nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
        if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
-       
 
        /* open print$-share on the src server */
-       nt_status = connect_to_service(&cli_share_src, &cli->dest_ip, 
+       nt_status = connect_to_service(&cli_share_src, &cli->dest_ss,
                        cli->desthost, "print$", "A:");
-       if (!NT_STATUS_IS_OK(nt_status)) 
+       if (!NT_STATUS_IS_OK(nt_status))
                goto done;
 
        got_src_driver_share = True;
 
 
        /* open print$-share on the dst server */
-       nt_status = connect_to_service(&cli_share_dst, &cli_dst->dest_ip, 
+       nt_status = connect_to_service(&cli_share_dst, &cli_dst->dest_ss,
                        cli_dst->desthost, "print$", "A:");
-       if (!NT_STATUS_IS_OK(nt_status)) 
+       if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
 
        got_dst_driver_share = True;
index 510807730ee0b75fd851528deff1f889959c87ad..7375206af63920c54789d1c40cb6d5ca040894a8 100644 (file)
@@ -23,7 +23,7 @@
 /*
   return the time on a server. This does not require any authentication
 */
-static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
+static time_t cli_servertime(const char *host, struct sockaddr_storage *pss, int *zone)
 {
        struct nmb_name calling, called;
        time_t ret = 0;
@@ -35,7 +35,7 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
                goto done;
        }
 
-       status = cli_connect(cli, host, ip);
+       status = cli_connect(cli, host, pss);
        if (!NT_STATUS_IS_OK(status)) {
                fprintf(stderr,"Can't contact server %s. Error %s\n", host, nt_errstr(status));
                goto done;
@@ -83,9 +83,9 @@ static const char *systime(time_t t)
        if (!tm) {
                return "unknown";
        }
-       
-       fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d", 
-                tm->tm_mon+1, tm->tm_mday, tm->tm_hour, 
+
+       fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
+                tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
                 tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
        return s;
 }
@@ -110,8 +110,8 @@ static int net_time_set(int argc, const char **argv)
        int result;
 
        if (t == 0) return -1;
-       
-       /* yes, I know this is cheesy. Use "net time system" if you want to 
+
+       /* yes, I know this is cheesy. Use "net time system" if you want to
           roll your own. I'm putting this in as it works on a large number
           of systems and the user has a choice in whether its used or not */
        asprintf(&cmd, "/bin/date %s", systime(t));
index 315a89d5a8c0f3983f7dcd2cc6b2e5f9ad9c6506..90f99e4c8b06661730dd7d3edc16f536ae23db74 100644 (file)
@@ -56,11 +56,15 @@ static int cs_destructor(struct con_struct *p)
 static struct con_struct *create_cs(TALLOC_CTX *ctx, NTSTATUS *perr)
 {
        NTSTATUS nt_status;
-       struct in_addr loopback_ip;
+       struct sockaddr_storage loopback_ss;
 
-       loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
        *perr = NT_STATUS_OK;
 
+       if (!interpret_string_addr(&loopback_ss, "127.0.0.1", AI_NUMERICHOST)) {
+               *perr = NT_STATUS_INVALID_PARAMETER;
+               return NULL;
+       }
+
        if (cs) {
                if (cs->failed_connect) {
                        *perr = cs->err;
@@ -90,7 +94,7 @@ static struct con_struct *create_cs(TALLOC_CTX *ctx, NTSTATUS *perr)
 #endif
 
        nt_status = cli_full_connection(&cs->cli, global_myname(), global_myname(),
-                                       &loopback_ip, 0,
+                                       &loopback_ss, 0,
                                        "IPC$", "IPC",
 #if 0
                                        opt_user_name,
index 1a26e81206e02030f544783ef71a047cfe497b09..e68c786ce97d45689c8bef7674ef6add9b59411a 100644 (file)
@@ -1,55 +1,66 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    NBT client - used to lookup netbios names
    Copyright (C) Andrew Tridgell 1994-1998
    Copyright (C) Jelmer Vernooij 2003 (Conversion to popt)
-   
+
    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/>.
-   
+
 */
 
 #include "includes.h"
 
 extern bool AllowDebugChange;
 
-static bool give_flags = False;
-static bool use_bcast = True;
-static bool got_bcast = False;
-static struct in_addr bcast_addr;
-static bool recursion_desired = False;
-static bool translate_addresses = False;
+static bool give_flags = false;
+static bool use_bcast = true;
+static bool got_bcast = false;
+static struct sockaddr_storage bcast_addr;
+static bool recursion_desired = false;
+static bool translate_addresses = false;
 static int ServerFD= -1;
-static bool RootPort = False;
-static bool find_status=False;
+static bool RootPort = false;
+static bool find_status = false;
 
 /****************************************************************************
-  open the socket communication
-  **************************************************************************/
+ Open the socket communication.
+**************************************************************************/
+
 static bool open_sockets(void)
 {
-  ServerFD = open_socket_in( SOCK_DGRAM,
-                             (RootPort ? 137 : 0),
-                             (RootPort ?   0 : 3),
-                             interpret_addr(lp_socket_address()), True );
+       struct sockaddr_storage ss;
+       const char *sock_addr = lp_socket_address();
+
+       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;
+       }
+       ServerFD = open_socket_in( SOCK_DGRAM,
+                               (RootPort ? 137 : 0),
+                               (RootPort ?   0 : 3),
+                               &ss, true );
 
-  if (ServerFD == -1)
-    return(False);
+       if (ServerFD == -1) {
+               return false;
+       }
 
-  set_socket_options( ServerFD, "SO_BROADCAST" );
+       set_socket_options( ServerFD, "SO_BROADCAST" );
 
-  DEBUG(3, ("Socket opened.\n"));
-  return True;
+       DEBUG(3, ("Socket opened.\n"));
+       return true;
 }
 
 /****************************************************************************
@@ -59,7 +70,7 @@ static char *node_status_flags(unsigned char flags)
 {
        static fstring ret;
        fstrcpy(ret,"");
-       
+
        fstrcat(ret, (flags & 0x80) ? "<GROUP> " : "        ");
        if ((flags & 0x60) == 0x00) fstrcat(ret,"B ");
        if ((flags & 0x60) == 0x20) fstrcat(ret,"P ");
@@ -69,13 +80,14 @@ static char *node_status_flags(unsigned char flags)
        if (flags & 0x08) fstrcat(ret,"<CONFLICT> ");
        if (flags & 0x04) fstrcat(ret,"<ACTIVE> ");
        if (flags & 0x02) fstrcat(ret,"<PERMANENT> ");
-       
+
        return ret;
 }
 
 /****************************************************************************
-turn the NMB Query flags into a string
+ Turn the NMB Query flags into a string.
 ****************************************************************************/
+
 static char *query_flags(int flags)
 {
        static fstring ret1;
@@ -92,24 +104,32 @@ static char *query_flags(int flags)
 }
 
 /****************************************************************************
-do a node status query
+ Do a node status query.
 ****************************************************************************/
-static void do_node_status(int fd, const char *name, int type, struct in_addr ip)
+
+static void do_node_status(int fd,
+               const char *name,
+               int type,
+               struct sockaddr_storage *pss)
 {
        struct nmb_name nname;
        int count, i, j;
        NODE_STATUS_STRUCT *status;
        struct node_status_extra extra;
        fstring cleanname;
+       char addr[INET6_ADDRSTRLEN];
 
-       d_printf("Looking up status of %s\n",inet_ntoa(ip));
+       print_sockaddr(addr, sizeof(addr), pss);
+       d_printf("Looking up status of %s\n",addr);
        make_nmb_name(&nname, name, type);
-       status = node_status_query(fd,&nname,ip, &count, &extra);
+       status = node_status_query(fd, &nname, pss, &count, &extra);
        if (status) {
                for (i=0;i<count;i++) {
                        pull_ascii_fstring(cleanname, status[i].name);
                        for (j=0;cleanname[j];j++) {
-                               if (!isprint((int)cleanname[j])) cleanname[j] = '.';
+                               if (!isprint((int)cleanname[j])) {
+                                       cleanname[j] = '.';
+                               }
                        }
                        d_printf("\t%-15s <%02x> - %s\n",
                               cleanname,status[i].type,
@@ -122,60 +142,80 @@ static void do_node_status(int fd, const char *name, int type, struct in_addr ip
                d_printf("\n");
                SAFE_FREE(status);
        } else {
-               d_printf("No reply from %s\n\n",inet_ntoa(ip));
+               d_printf("No reply from %s\n\n",addr);
        }
 }
 
 
 /****************************************************************************
-send out one query
+ Send out one query.
 ****************************************************************************/
+
 static bool query_one(const char *lookup, unsigned int lookup_type)
 {
        int j, count, flags = 0;
-       struct in_addr *ip_list=NULL;
+       struct sockaddr_storage *ip_list=NULL;
 
        if (got_bcast) {
-               d_printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &bcast_addr);
+               d_printf("querying %s on %s\n", lookup, addr);
                ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
-                                    use_bcast?True:recursion_desired,
-                                    bcast_addr,&count, &flags, NULL);
+                                    use_bcast?true:recursion_desired,
+                                    &bcast_addr, &count, &flags, NULL);
        } else {
                const struct in_addr *bcast;
                for (j=iface_count() - 1;
                     !ip_list && j >= 0;
                     j--) {
+                       char addr[INET6_ADDRSTRLEN];
+                       struct sockaddr_storage bcast_ss;
+
                        bcast = iface_n_bcast_v4(j);
                        if (!bcast) {
                                continue;
                        }
-                       d_printf("querying %s on %s\n", 
-                              lookup, inet_ntoa(*bcast));
+                       in_addr_to_sockaddr_storage(&bcast_ss, *bcast);
+                       print_sockaddr(addr, sizeof(addr), &bcast_ss);
+                       d_printf("querying %s on %s\n",
+                              lookup, addr);
                        ip_list = name_query(ServerFD,lookup,lookup_type,
                                             use_bcast,
                                             use_bcast?True:recursion_desired,
-                                            *bcast,&count, &flags, NULL);
+                                            &bcast_ss,&count, &flags, NULL);
                }
        }
 
-       if (!ip_list) return False;
+       if (!ip_list) {
+               return false;
+       }
 
-       if (give_flags)
-         d_printf("Flags: %s\n", query_flags(flags));
+       if (give_flags) {
+               d_printf("Flags: %s\n", query_flags(flags));
+       }
 
        for (j=0;j<count;j++) {
+               char addr[INET6_ADDRSTRLEN];
                if (translate_addresses) {
-                       struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
-                       if (host) {
-                               d_printf("%s, ", host -> h_name);
+                       char h_name[HOST_NAME_MAX];
+                       h_name[0] = '\0';
+                       if (getnameinfo((const struct sockaddr *)&ip_list[j],
+                                       sizeof(struct sockaddr_storage),
+                                       h_name, sizeof(h_name),
+                                       NULL, 0,
+                                       NI_NAMEREQD)) {
+                               continue;
                        }
+                       d_printf("%s, ", h_name);
                }
-               d_printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
+               print_sockaddr(addr, sizeof(addr), &ip_list[j]);
+               d_printf("%s %s<%02x>\n", addr,lookup, lookup_type);
                /* We can only do find_status if the ip address returned
                   was valid - ie. name_query returned true.
                 */
                if (find_status) {
-                       do_node_status(ServerFD, lookup, lookup_type, ip_list[j]);
+                       do_node_status(ServerFD, lookup,
+                                       lookup_type, &ip_list[j]);
                }
        }
 
@@ -190,130 +230,140 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
 ****************************************************************************/
 int main(int argc,char *argv[])
 {
-  int opt;
-  unsigned int lookup_type = 0x0;
-  fstring lookup;
-  static bool find_master=False;
-  static bool lookup_by_ip = False;
-  poptContext pc;
-  TALLOC_CTX *frame = talloc_stackframe();
-
-  struct poptOption long_options[] = {
-         POPT_AUTOHELP
-         { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
-         { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" },
-         { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
-         { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" },
-         { "recursion", 'R', POPT_ARG_VAL, NULL, 'R', "Set recursion desired in package" },
-         { "status", 'S', POPT_ARG_VAL, NULL, 'S', "Lookup node status as well" },
-         { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
-         { "root-port", 'r', POPT_ARG_VAL, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
-         { "lookup-by-ip", 'A', POPT_ARG_VAL, NULL, 'A', "Do a node status on <name> as an IP Address" },
-         POPT_COMMON_SAMBA
-         POPT_COMMON_CONNECTION
-         { 0, 0, 0, 0 }
-  };
-       
-  *lookup = 0;
-
-  load_case_tables();
-
-  setup_logging(argv[0],True);
-
-  pc = poptGetContext("nmblookup", argc, (const char **)argv, long_options, 
-                                         POPT_CONTEXT_KEEP_FIRST);
-
-  poptSetOtherOptionHelp(pc, "<NODE> ...");
-
-  while ((opt = poptGetNextOpt(pc)) != -1) {
-         switch (opt) {
-         case 'f':
-                 give_flags = true;
-                 break;
-         case 'M':
-                 find_master = true;
-                 break;
-         case 'R':
-                 recursion_desired = true;
-                 break;
-         case 'S':
-                 find_status = true;
-                 break;
-         case 'r':
-                 RootPort = true;
-                 break;
-         case 'A':
-                 lookup_by_ip = true;
-                 break;
-         case 'B':
-                 bcast_addr = *interpret_addr2(poptGetOptArg(pc));
-                 got_bcast = True;
-                 use_bcast = True;
-                 break;
-         case 'U':
-                 bcast_addr = *interpret_addr2(poptGetOptArg(pc));
-                 got_bcast = True;
-                 use_bcast = False;
-                 break;
-         case 'T':
-                 translate_addresses = !translate_addresses;
-                 break;
-         }
-  }
-
-  poptGetArg(pc); /* Remove argv[0] */
-
-  if(!poptPeekArg(pc)) { 
-         poptPrintUsage(pc, stderr, 0);
-         exit(1);
-  }
-
-  if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
-         fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
-  }
-
-  load_interfaces();
-  if (!open_sockets()) return(1);
-
-  while(poptPeekArg(pc))
-  {
-         char *p;
-         struct in_addr ip;
-
-         fstrcpy(lookup,poptGetArg(pc));
-
-         if(lookup_by_ip)
-         {
-                 ip = *interpret_addr2(lookup);
-                 fstrcpy(lookup,"*");
-                 do_node_status(ServerFD, lookup, lookup_type, ip);
-                 continue;
-         }
-
-         if (find_master) {
-                 if (*lookup == '-') {
-                         fstrcpy(lookup,"\01\02__MSBROWSE__\02");
-                         lookup_type = 1;
-                 } else {
-                         lookup_type = 0x1d;
-                 }
-         }
-
-         p = strchr_m(lookup,'#');
-         if (p) {
-                 *p = '\0';
-                 sscanf(++p,"%x",&lookup_type);
-         }
-
-         if (!query_one(lookup, lookup_type)) {
-                 d_printf( "name_query failed to find name %s", lookup );
-                 if( 0 != lookup_type )
-                         d_printf( "#%02x", lookup_type );
-                 d_printf( "\n" );
-         }
-  }
-
-  poptFreeContext(pc);
-  TALLOC_FREE(frame);
-  return(0);
+       int opt;
+       unsigned int lookup_type = 0x0;
+       fstring lookup;
+       static bool find_master=False;
+       static bool lookup_by_ip = False;
+       poptContext pc;
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       struct poptOption long_options[] = {
+               POPT_AUTOHELP
+               { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
+               { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" },
+               { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
+               { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" },
+               { "recursion", 'R', POPT_ARG_VAL, NULL, 'R', "Set recursion desired in package" },
+               { "status", 'S', POPT_ARG_VAL, NULL, 'S', "Lookup node status as well" },
+               { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
+               { "root-port", 'r', POPT_ARG_VAL, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
+               { "lookup-by-ip", 'A', POPT_ARG_VAL, NULL, 'A', "Do a node status on <name> as an IP Address" },
+               POPT_COMMON_SAMBA
+               POPT_COMMON_CONNECTION
+               { 0, 0, 0, 0 }
+       };
+
+       *lookup = 0;
+
+       load_case_tables();
+
+       setup_logging(argv[0],True);
+
+       pc = poptGetContext("nmblookup", argc, (const char **)argv,
+                       long_options, POPT_CONTEXT_KEEP_FIRST);
+
+       poptSetOtherOptionHelp(pc, "<NODE> ...");
+
+       while ((opt = poptGetNextOpt(pc)) != -1) {
+               switch (opt) {
+               case 'f':
+                       give_flags = true;
+                       break;
+               case 'M':
+                       find_master = true;
+                       break;
+               case 'R':
+                       recursion_desired = true;
+                       break;
+               case 'S':
+                       find_status = true;
+                       break;
+               case 'r':
+                       RootPort = true;
+                       break;
+               case 'A':
+                       lookup_by_ip = true;
+                       break;
+               case 'B':
+                       if (interpret_string_addr(&bcast_addr,
+                                       poptGetOptArg(pc),
+                                       NI_NUMERICHOST)) {
+                               got_bcast = True;
+                               use_bcast = True;
+                       }
+                       break;
+               case 'U':
+                       if (interpret_string_addr(&bcast_addr,
+                                       poptGetOptArg(pc),
+                                       0)) {
+                               got_bcast = True;
+                               use_bcast = False;
+                       }
+                       break;
+               case 'T':
+                       translate_addresses = !translate_addresses;
+                       break;
+               }
+       }
+
+       poptGetArg(pc); /* Remove argv[0] */
+
+       if(!poptPeekArg(pc)) {
+               poptPrintUsage(pc, stderr, 0);
+               exit(1);
+       }
+
+       if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
+               fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+                               dyn_CONFIGFILE);
+       }
+
+       load_interfaces();
+       if (!open_sockets()) {
+               return(1);
+       }
+
+       while(poptPeekArg(pc)) {
+               char *p;
+               struct in_addr ip;
+
+               fstrcpy(lookup,poptGetArg(pc));
+
+               if(lookup_by_ip) {
+                       struct sockaddr_storage ss;
+                       ip = *interpret_addr2(lookup);
+                       in_addr_to_sockaddr_storage(&ss, ip);
+                       fstrcpy(lookup,"*");
+                       do_node_status(ServerFD, lookup, lookup_type, &ss);
+                       continue;
+               }
+
+               if (find_master) {
+                       if (*lookup == '-') {
+                               fstrcpy(lookup,"\01\02__MSBROWSE__\02");
+                               lookup_type = 1;
+                       } else {
+                               lookup_type = 0x1d;
+                       }
+               }
+
+               p = strchr_m(lookup,'#');
+               if (p) {
+                       *p = '\0';
+                       sscanf(++p,"%x",&lookup_type);
+               }
+
+               if (!query_one(lookup, lookup_type)) {
+                       d_printf( "name_query failed to find name %s", lookup );
+                       if( 0 != lookup_type ) {
+                               d_printf( "#%02x", lookup_type );
+                       }
+                       d_printf( "\n" );
+               }
+       }
+
+       poptFreeContext(pc);
+       TALLOC_FREE(frame);
+       return(0);
 }
index b8b29b44eb67dd51bd548b356ad5071b748e4e2e..d5bf9b96e661f765357f141ca7b972f144eed2ac 100644 (file)
@@ -760,16 +760,17 @@ static int cacl_set(struct cli_state *cli, char *filename,
 }
 
 
-/***************************************************** 
-return a connection to a server
+/*****************************************************
+ Return a connection to a server.
 *******************************************************/
+
 static struct cli_state *connect_one(const char *share)
 {
        struct cli_state *c;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        NTSTATUS nt_status;
-       zero_ip_v4(&ip);
-       
+       zero_addr(&ss, AF_INET);
+
        if (!cmdline_auth_info.got_pass) {
                char *pass = getpass("Password: ");
                if (pass) {
@@ -779,8 +780,8 @@ static struct cli_state *connect_one(const char *share)
        }
 
        if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server, 
-                                                           &ip, 0,
-                                                           share, "?????",  
+                                                           &ss, 0,
+                                                           share, "?????",
                                                            cmdline_auth_info.username, lp_workgroup(),
                                                            cmdline_auth_info.password, 0,
                                                            cmdline_auth_info.signing_state, NULL))) {
index a3d90f823b919807a8f27cd70f4da766dd323e56..f185caa50f73b6c3bfa11266f63ba6b55d7be50f 100644 (file)
@@ -352,16 +352,17 @@ static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd
        return 0;
 }
 
-/***************************************************** 
-return a connection to a server
+/*****************************************************
+ Return a connection to a server.
 *******************************************************/
+
 static struct cli_state *connect_one(const char *share)
 {
        struct cli_state *c;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
        NTSTATUS nt_status;
-       zero_ip_v4(&ip);
-       
+       zero_addr(&ss, AF_INET);
+
        if (!cmdline_auth_info.got_pass) {
                char *pass = getpass("Password: ");
                if (pass) {
@@ -371,8 +372,8 @@ static struct cli_state *connect_one(const char *share)
        }
 
        if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server, 
-                                                           &ip, 0,
-                                                           share, "?????",  
+                                                           &ss, 0,
+                                                           share, "?????",
                                                            cmdline_auth_info.username, lp_workgroup(),
                                                            cmdline_auth_info.password, 0,
                                                            cmdline_auth_info.signing_state, NULL))) {
index df3b34dd16430d6281dacd776918e4fc536ea828..221ce83f82780863c3248522d059d20ad241bea0 100644 (file)
@@ -36,16 +36,18 @@ bool nmbd_running(void)
 {
        struct in_addr loopback_ip;
        int fd, count, flags;
-       struct in_addr *ip_list;
+       struct sockaddr_storage *ss_list;
+       struct sockaddr_storage ss;
 
        loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+       in_addr_to_sockaddr_storage(&ss, loopback_ip);
 
        if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
-                                interpret_addr("127.0.0.1"), True)) != -1) {
-               if ((ip_list = name_query(fd, "__SAMBA__", 0, 
-                                         True, True, loopback_ip,
+                                &ss, True)) != -1) {
+               if ((ss_list = name_query(fd, "__SAMBA__", 0, 
+                                         True, True, &ss,
                                          &count, &flags, NULL)) != NULL) {
-                       SAFE_FREE(ip_list);
+                       SAFE_FREE(ss_list);
                        close(fd);
                        return True;
                }
@@ -63,13 +65,15 @@ bool smbd_running(void)
        struct in_addr loopback_ip;
        NTSTATUS status;
        struct cli_state *cli;
+       struct sockaddr_storage ss;
 
        loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+       in_addr_to_sockaddr_storage(&ss, loopback_ip);
 
        if ((cli = cli_initialise()) == NULL)
                return False;
 
-       status = cli_connect(cli, global_myname(), &loopback_ip);
+       status = cli_connect(cli, global_myname(), &ss);
        if (!NT_STATUS_IS_OK(status)) {
                cli_shutdown(cli);
                return False;
index e4b1396cac4ff8300b829f7de502631e6ce0b362..454a4b9698bfb4e888381ebebbc8a7749f0d31a7 100644 (file)
@@ -191,7 +191,7 @@ struct winbindd_domain {
 
        /* A working DC */
        fstring dcname;
-       struct sockaddr_in dcaddr;
+       struct sockaddr_storage dcaddr;
 
        /* Sequence number stuff */
 
index 3f3f06e3fd5577ae9693d98d9669c9baa7c1480e..6549c6d7d23e8be0e451101920131e055392b942 100644 (file)
@@ -40,7 +40,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        ADS_STRUCT *ads;
        ADS_STATUS status;
        fstring dc_name;
-       struct in_addr dc_ip;   
+       struct sockaddr_storage dc_ss;
 
        DEBUG(10,("ads_cached_connection\n"));
 
@@ -66,7 +66,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                        ads_destroy( &ads );
                        ads_kdestroy("MEMORY:winbind_ccache");
                        domain->private_data = NULL;
-               }       
+               }
        }
 
        /* we don't want this to affect the users ccache */
@@ -99,7 +99,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 
                ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
 
-               /* always give preference to the alt_name in our 
+               /* always give preference to the alt_name in our
                   primary domain if possible */
 
                if ( !domain->primary )
@@ -116,14 +116,14 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME;
 
        /* Setup the server affinity cache.  We don't reaally care
-          about the name.  Just setup affinity and the KRB5_CONFIG 
+          about the name.  Just setup affinity and the KRB5_CONFIG
           file. */
 
-       get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ip );
-       
+       get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss );
+
        status = ads_connect(ads);
        if (!ADS_ERR_OK(status) || !ads->config.realm) {
-               DEBUG(1,("ads_connect for domain %s failed: %s\n", 
+               DEBUG(1,("ads_connect for domain %s failed: %s\n",
                         domain->name, ads_errstr(status)));
                ads_destroy(&ads);
 
@@ -138,8 +138,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                return NULL;
        }
 
-       /* set the flag that says we don't own the memory even 
-          though we do so that ads_destroy() won't destroy the 
+       /* set the flag that says we don't own the memory even
+          though we do so that ads_destroy() won't destroy the
           structure we pass back by reference */
 
        ads->is_mine = False;
index 055563d815dcf64d006d92a8352632af635d7639..4c9ae0365fc730bee8d243d841b59be2ac4cd985 100644 (file)
@@ -66,7 +66,7 @@
 
 struct dc_name_ip {
        fstring name;
-       struct in_addr ip;
+       struct sockaddr_storage ss;
 };
 
 extern struct winbindd_methods reconnect_methods;
@@ -559,7 +559,8 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
 }
 
 static bool get_dc_name_via_netlogon(const struct winbindd_domain *domain,
-                                    fstring dcname, struct in_addr *dc_ip)
+                                    fstring dcname,
+                                    struct sockaddr_storage *dc_ss)
 {
        struct winbindd_domain *our_domain = NULL;
        struct rpc_pipe_client *netlogon_pipe = NULL;
@@ -625,7 +626,7 @@ static bool get_dc_name_via_netlogon(const struct winbindd_domain *domain,
 
        DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname));
 
-       if (!resolve_name(dcname, dc_ip, 0x20)) {
+       if (!resolve_name(dcname, dc_ss, 0x20)) {
                return False;
        }
 
@@ -891,7 +892,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
 }
 
 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
-                             const char *dcname, struct in_addr ip,
+                             const char *dcname, struct sockaddr_storage *pss,
                              struct dc_name_ip **dcs, int *num)
 {
        if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
@@ -905,26 +906,23 @@ static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
                return False;
 
        fstrcpy((*dcs)[*num].name, dcname);
-       (*dcs)[*num].ip = ip;
+       (*dcs)[*num].ss = *pss;
        *num += 1;
        return True;
 }
 
 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
-                                 struct in_addr ip, uint16 port,
-                                 struct sockaddr_in **addrs, int *num)
+                                 struct sockaddr_storage *pss, uint16 port,
+                                 struct sockaddr_storage **addrs, int *num)
 {
-       *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
+       *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
 
        if (*addrs == NULL) {
                *num = 0;
                return False;
        }
 
-       (*addrs)[*num].sin_family = PF_INET;
-       putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
-       (*addrs)[*num].sin_port = htons(port);
-
+       (*addrs)[*num] = *pss;
        *num += 1;
        return True;
 }
@@ -934,15 +932,21 @@ static void mailslot_name(struct in_addr dc_ip, fstring name)
        fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
 }
 
-static bool send_getdc_request(struct in_addr dc_ip,
+static bool send_getdc_request(struct sockaddr_storage *dc_ss,
                               const char *domain_name,
                               const DOM_SID *sid)
 {
-       pstring outbuf;
+       char outbuf[1024];
+       struct in_addr dc_ip;
        char *p;
        fstring my_acct_name;
        fstring my_mailslot;
 
+       if (dc_ss->ss_family != AF_INET) {
+               return false;
+       }
+
+       dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr;
        mailslot_name(dc_ip, my_mailslot);
 
        memset(outbuf, '\0', sizeof(outbuf));
@@ -958,13 +962,23 @@ static bool send_getdc_request(struct in_addr dc_ip,
        SIVAL(p, 0, 0); /* The sender's token ... */
        p += 2;
 
-       p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
+       p += dos_PutUniCode(p, global_myname(),
+                       sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
        fstr_sprintf(my_acct_name, "%s$", global_myname());
-       p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
+       p += dos_PutUniCode(p, my_acct_name,
+                       sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
+
+       if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+               return false;
+       }
 
        memcpy(p, my_mailslot, strlen(my_mailslot)+1);
        p += strlen(my_mailslot)+1;
 
+       if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) {
+               return false;
+       }
+
        SIVAL(p, 0, 0x80);
        p+=4;
 
@@ -972,8 +986,15 @@ static bool send_getdc_request(struct in_addr dc_ip,
        p+=4;
 
        p = ALIGN4(p, outbuf);
+       if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) {
+               return false;
+       }
 
        sid_linearize(p, sid_size(sid), sid);
+       if (sid_size(sid) + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+               return false;
+       }
+
        p += sid_size(sid);
 
        SIVAL(p, 0, 1);
@@ -985,10 +1006,10 @@ static bool send_getdc_request(struct in_addr dc_ip,
                                 False, "\\MAILSLOT\\NET\\NTLOGON", 0,
                                 outbuf, PTR_DIFF(p, outbuf),
                                 global_myname(), 0, domain_name, 0x1c,
-                                dc_ip);
+                                dc_ss);
 }
 
-static bool receive_getdc_response(struct in_addr dc_ip,
+static bool receive_getdc_response(struct sockaddr_storage *dc_ss,
                                   const char *domain_name,
                                   fstring dc_name)
 {
@@ -997,7 +1018,12 @@ static bool receive_getdc_response(struct in_addr dc_ip,
        char *buf, *p;
        fstring dcname, user, domain;
        int len;
+       struct in_addr dc_ip;
 
+       if (dc_ss->ss_family != AF_INET) {
+               return false;
+       }
+       dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr;
        mailslot_name(dc_ip, my_mailslot);
 
        packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
@@ -1060,11 +1086,13 @@ static bool receive_getdc_response(struct in_addr dc_ip,
  convert an ip to a name
 *******************************************************************/
 
-static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip, fstring name )
+static bool dcip_to_name(const struct winbindd_domain *domain,
+               struct sockaddr_storage *pss,
+               fstring name )
 {
        struct ip_service ip_list;
 
-       ip_list.ip = ip;
+       ip_list.ss = *pss;
        ip_list.port = 0;
 
 #ifdef WITH_ADS
@@ -1073,11 +1101,14 @@ static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
 
        if (lp_security() == SEC_ADS) {
                ADS_STRUCT *ads;
+               char addr[INET6_ADDRSTRLEN];
+
+               print_sockaddr(addr, sizeof(addr), pss);
 
                ads = ads_init(domain->alt_name, domain->name, NULL);
                ads->auth.flags |= ADS_AUTH_NO_BIND;
 
-               if (ads_try_connect( ads, inet_ntoa(ip) ) )  {
+               if (ads_try_connect(ads, addr)) {
                        /* We got a cldap packet. */
                        fstrcpy(name, ads->config.ldap_server_name);
                        namecache_store(name, 0x20, 1, &ip_list);
@@ -1095,7 +1126,7 @@ static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
                                        create_local_private_krb5_conf_for_domain(domain->alt_name,
                                                                        domain->name,
                                                                        sitename,
-                                                                       ip);
+                                                                       pss);
 
                                        SAFE_FREE(sitename);
                                } else {
@@ -1103,7 +1134,7 @@ static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
                                        create_local_private_krb5_conf_for_domain(domain->alt_name,
                                                                        domain->name,
                                                                        NULL,
-                                                                       ip);
+                                                                       pss);
                                }
                                winbindd_set_locator_kdc_envs(domain);
 
@@ -1121,12 +1152,12 @@ static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
 #endif
 
        /* try GETDC requests next */
-       
-       if (send_getdc_request(ip, domain->name, &domain->sid)) {
+
+       if (send_getdc_request(pss, domain->name, &domain->sid)) {
                int i;
                smb_msleep(100);
                for (i=0; i<5; i++) {
-                       if (receive_getdc_response(ip, domain->name, name)) {
+                       if (receive_getdc_response(pss, domain->name, name)) {
                                namecache_store(name, 0x20, 1, &ip_list);
                                return True;
                        }
@@ -1136,7 +1167,7 @@ static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
 
        /* try node status request */
 
-       if ( name_status_find(domain->name, 0x1c, 0x20, ip, name) ) {
+       if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
                namecache_store(name, 0x20, 1, &ip_list);
                return True;
        }
@@ -1152,7 +1183,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
                    struct dc_name_ip **dcs, int *num_dcs)
 {
        fstring dcname;
-       struct  in_addr ip;
+       struct  sockaddr_storage ss;
        struct  ip_service *ip_list = NULL;
        int     iplist_size = 0;
        int     i;
@@ -1161,12 +1192,14 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
 
        is_our_domain = strequal(domain->name, lp_workgroup());
 
-       if ( !is_our_domain 
-               && get_dc_name_via_netlogon(domain, dcname, &ip) 
-               && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
+       if ( !is_our_domain
+               && get_dc_name_via_netlogon(domain, dcname, &ss)
+               && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs, num_dcs) )
        {
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &ss);
                DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
-                          dcname, inet_ntoa(ip)));
+                          dcname, addr));
                return True;
        }
 
@@ -1182,7 +1215,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
                   We deliberately don't care about the
                   return here. */
 
-               get_dc_name(domain->name, domain->alt_name, dcname, &ip);
+               get_dc_name(domain->name, domain->alt_name, dcname, &ss);
 
                sitename = sitename_fetch(domain->alt_name);
                if (sitename) {
@@ -1191,8 +1224,15 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
                        get_sorted_dc_list(domain->alt_name, sitename, &ip_list, &iplist_size, True);
 
                        for ( i=0; i<iplist_size; i++ ) {
-                               add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
-                                                       ip_list[i].ip, dcs, num_dcs);
+                               char addr[INET6_ADDRSTRLEN];
+                               print_sockaddr(addr, sizeof(addr),
+                                               &ip_list[i].ss);
+                               add_one_dc_unique(mem_ctx,
+                                               domain->name,
+                                               addr,
+                                               &ip_list[i].ss,
+                                               dcs,
+                                               num_dcs);
                        }
 
                        SAFE_FREE(ip_list);
@@ -1204,8 +1244,15 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
                get_sorted_dc_list(domain->alt_name, NULL, &ip_list, &iplist_size, True);
 
                for ( i=0; i<iplist_size; i++ ) {
-                       add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
-                                               ip_list[i].ip, dcs, num_dcs);
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr),
+                                       &ip_list[i].ss);
+                       add_one_dc_unique(mem_ctx,
+                                       domain->name,
+                                       addr,
+                                       &ip_list[i].ss,
+                                       dcs,
+                                       num_dcs);
                }
         }
 
@@ -1222,8 +1269,11 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
           the ip now in to make the failed connection cache work */
 
        for ( i=0; i<iplist_size; i++ ) {
-               add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip), 
-                       ip_list[i].ip, dcs, num_dcs);
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr),
+                               &ip_list[i].ss);
+               add_one_dc_unique(mem_ctx, domain->name, addr,
+                       &ip_list[i].ss, dcs, num_dcs);
        }
 
        SAFE_FREE( ip_list );
@@ -1233,7 +1283,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
 
 static bool find_new_dc(TALLOC_CTX *mem_ctx,
                        const struct winbindd_domain *domain,
-                       fstring dcname, struct sockaddr_in *addr, int *fd)
+                       fstring dcname, struct sockaddr_storage *pss, int *fd)
 {
        struct dc_name_ip *dcs = NULL;
        int num_dcs = 0;
@@ -1241,7 +1291,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx,
        const char **dcnames = NULL;
        int num_dcnames = 0;
 
-       struct sockaddr_in *addrs = NULL;
+       struct sockaddr_storage *addrs = NULL;
        int num_addrs = 0;
 
        int i, fd_index;
@@ -1256,7 +1306,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx,
                                    &dcnames, &num_dcnames)) {
                        return False;
                }
-               if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
+               if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
                                      &addrs, &num_addrs)) {
                        return False;
                }
@@ -1265,7 +1315,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx,
                                    &dcnames, &num_dcnames)) {
                        return False;
                }
-               if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
+               if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 139,
                                      &addrs, &num_addrs)) {
                        return False;
                }
@@ -1278,28 +1328,29 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx,
                return False;
 
        /* 5 second timeout. */
-       if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) 
-       {
+       if (!open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) {
                for (i=0; i<num_dcs; i++) {
+                       char ab[INET6_ADDRSTRLEN];
+                       print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
                        DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
                                "domain %s address %s. Error was %s\n",
-                               domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
+                               domain->name, ab, strerror(errno) ));
                        winbind_add_failed_connection_entry(domain,
                                dcs[i].name, NT_STATUS_UNSUCCESSFUL);
                }
                return False;
        }
 
-       *addr = addrs[fd_index];
+       *pss = addrs[fd_index];
 
-       if (*dcnames[fd_index] != '\0' && !is_ipaddress_v4(dcnames[fd_index])) {
+       if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
                /* Ok, we've got a name for the DC */
                fstrcpy(dcname, dcnames[fd_index]);
                return True;
        }
 
        /* Try to figure out the name */
-       if (dcip_to_name( domain, addr->sin_addr, dcname )) {
+       if (dcip_to_name(domain, pss, dcname)) {
                return True;
        }
 
@@ -1336,12 +1387,15 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
                        saf_servername, domain->name ));
 
                /* convert an ip address to a name */
-               if ( is_ipaddress_v4( saf_servername ) ) {
+               if (is_ipaddress( saf_servername ) ) {
                        fstring saf_name;
-                       struct in_addr ip;
+                       struct sockaddr_storage ss;
 
-                       ip = *interpret_addr2( saf_servername );
-                       if (dcip_to_name( domain, ip, saf_name )) {
+                       if (!interpret_string_addr(&ss, saf_servername,
+                                               AI_NUMERICHOST)) {
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+                       if (dcip_to_name( domain, &ss, saf_name )) {
                                fstrcpy( domain->dcname, saf_name );
                        } else {
                                winbind_add_failed_connection_entry(
@@ -1356,7 +1410,6 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
        }
 
        for (retries = 0; retries < 3; retries++) {
-
                int fd = -1;
                bool retry = False;
 
@@ -1367,18 +1420,18 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
 
                if (*domain->dcname 
                        && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
-                       && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
+                       && (resolve_name(domain->dcname, &domain->dcaddr, 0x20)))
                {
-                       struct sockaddr_in *addrs = NULL;
+                       struct sockaddr_storage *addrs = NULL;
                        int num_addrs = 0;
                        int dummy = 0;
 
-                       if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
+                       if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 445, &addrs, &num_addrs)) {
                                set_domain_offline(domain);
                                talloc_destroy(mem_ctx);
                                return NT_STATUS_NO_MEMORY;
                        }
-                       if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
+                       if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 139, &addrs, &num_addrs)) {
                                set_domain_offline(domain);
                                talloc_destroy(mem_ctx);
                                return NT_STATUS_NO_MEMORY;
index 7035f6bffbc9fdf49f9f8185bc0a77b5536da795..55212a84b8cc8d4f908b8996b7aa3d0f16f08137 100644 (file)
@@ -843,20 +843,20 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
 
 /**********************************************************************
  Get the sequence number for a Windows AD native mode domain using
- LDAP queries. 
+ LDAP queries.
 **********************************************************************/
 
 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
 {
        int ret = -1;
-       fstring ipstr;
+       char addr[INET6_ADDRSTRLEN];
 
-       fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
-       if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
+       print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
+       if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
                DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
-                         "number for Domain (%s) from DC (%s)\n", 
-                       domain->name, ipstr));
-       } 
+                         "number for Domain (%s) from DC (%s)\n",
+                       domain->name, addr));
+       }
        return ret;
 }
 
@@ -877,7 +877,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
        if ( !winbindd_can_contact_domain( domain ) ) {
                DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
                          domain->name));
-               *seq = time(NULL);              
+               *seq = time(NULL);
                return NT_STATUS_OK;
        }
 
index 8970c1faf915e4613964ccbc3cc6c1e0c51053a6..5c8c8ea13de21bbcdadf92f8db6900ad5522c927 100644 (file)
@@ -1438,6 +1438,7 @@ bool winbindd_internal_child(struct winbindd_child *child)
 static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain)
 {
        char *var = NULL;
+       char addr[INET6_ADDRSTRLEN];
        const char *kdc = NULL;
        int lvl = 11;
 
@@ -1451,8 +1452,9 @@ static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain)
                return;
        }
 
-       kdc = inet_ntoa(domain->dcaddr.sin_addr);
-       if (!kdc) {
+       print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
+       kdc = addr;
+       if (!*kdc) {
                DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n",
                        domain->alt_name));
                kdc = domain->dcname;
index 2ee6f69b66a77ff75b25ce2b8a3f7e06e3df60cf..4a3d2682b65f325ae62592878519cca93c4ca9cc 100644 (file)
@@ -64,10 +64,10 @@ static int wins_lookup_open_socket_in(void)
 }
 
 
-static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
+static NODE_STATUS_STRUCT *lookup_byaddr_backend(const char *addr, int *count)
 {
        int fd;
-       struct in_addr  ip;
+       struct sockaddr_storage ss;
        struct nmb_name nname;
        NODE_STATUS_STRUCT *status;
 
@@ -76,18 +76,21 @@ static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
                return NULL;
 
        make_nmb_name(&nname, "*", 0);
-       ip = *interpret_addr2(addr);
-       status = node_status_query(fd,&nname,ip, count, NULL);
+       if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
+               return NULL;
+       }
+       status = node_status_query(fd, &nname, &ss, count, NULL);
 
        close(fd);
        return status;
 }
 
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
+static struct sockaddr_storage *lookup_byname_backend(const char *name,
+                                       int *count)
 {
        int fd;
        struct ip_service *ret = NULL;
-       struct in_addr *return_ip = NULL;
+       struct sockaddr_storage *return_ss = NULL;
        int j, i, flags = 0;
 
        *count = 0;
@@ -96,17 +99,17 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
        if (NT_STATUS_IS_OK(resolve_wins(name,0x20,&ret,count))) {
                if ( *count == 0 )
                        return NULL;
-               if ( (return_ip = SMB_MALLOC_ARRAY(struct in_addr, *count)) == NULL ) {
+               if ( (return_ss = SMB_MALLOC_ARRAY(struct sockaddr_storage, *count)) == NULL ) {
                        free( ret );
                        return NULL;
                }
 
                /* copy the IP addresses */
-               for ( i=0; i<(*count); i++ ) 
-                       return_ip[i] = ret[i].ip;
-               
+               for ( i=0; i<(*count); i++ )
+                       return_ss[i] = ret[i].ss;
+
                free( ret );
-               return return_ip;
+               return return_ss;
        }
 
        fd = wins_lookup_open_socket_in();
@@ -118,18 +121,18 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
        for (j=iface_count() - 1;
             j >= 0;
             j--) {
-               const struct in_addr *bcast = iface_n_bcast_v4(j);
-               if (!bcast) {
+               const struct sockaddr_storage *bcast_ss = iface_n_bcast(j);
+               if (!bcast_ss) {
                        continue;
                }
-               return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
-               if (return_ip) {
+               return_ss = name_query(fd,name,0x20,True,True,bcast_ss,count, &flags, NULL);
+               if (return_ss) {
                        break;
                }
        }
 
        close(fd);
-       return return_ip;
+       return return_ss;
 }
 
 /* Get hostname from IP  */
@@ -184,10 +187,10 @@ void winbindd_wins_byip(struct winbindd_cli_state *state)
 
 void winbindd_wins_byname(struct winbindd_cli_state *state)
 {
-       struct in_addr *ip_list;
+       struct sockaddr_storage *ip_list = NULL;
        int i, count, maxlen, size;
        fstring response;
-       char * addr;
+       char addr[INET6_ADDRSTRLEN];
 
        /* Ensure null termination */
        state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
@@ -200,29 +203,30 @@ void winbindd_wins_byname(struct winbindd_cli_state *state)
 
        if ((ip_list = lookup_byname_backend(state->request.data.winsreq,&count))){
                for (i = count; i ; i--) {
-                   addr = inet_ntoa(ip_list[i-1]);
-                   size = strlen(addr);
-                   if (size > maxlen) {
-                       SAFE_FREE(ip_list);
-                       request_error(state);
-                       return;
-                   }
-                   if (i != 0) {
-                       /* Clear out the newline character */
-                       /* But only if there is something in there, 
-                          otherwise we clobber something in the stack */
-                       if (strlen(response))
-                               response[strlen(response)-1] = ' '; 
-                   }
-                   fstrcat(response,addr);
-                   fstrcat(response,"\t");
+                       print_sockaddr(addr, sizeof(addr), &ip_list[i-1]);
+                       size = strlen(addr);
+                       if (size > maxlen) {
+                               SAFE_FREE(ip_list);
+                               request_error(state);
+                               return;
+                       }
+                       if (i != 0) {
+                               /* Clear out the newline character */
+                               /* But only if there is something in there,
+                               otherwise we clobber something in the stack */
+                               if (strlen(response)) {
+                                       response[strlen(response)-1] = ' ';
+                               }
+                       }
+                       fstrcat(response,addr);
+                       fstrcat(response,"\t");
                }
                size = strlen(state->request.data.winsreq) + strlen(response);
                if (size > maxlen) {
                    SAFE_FREE(ip_list);
                    request_error(state);
                    return;
-               }   
+               }
                fstrcat(response,state->request.data.winsreq);
                fstrcat(response,"\n");
                SAFE_FREE(ip_list);