summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-10-24 14:16:54 -0700
committerJeremy Allison <jra@samba.org>2007-10-24 14:16:54 -0700
commitf88b7a076be74a29a3bf876b4e2705f4a1ecf42b (patch)
tree2d5167540fcbe1ad245fce697924b18216b2d142 /source3
parente01cbcb28e63abb0f681a5a168fc2445744eec93 (diff)
downloadsamba-f88b7a076be74a29a3bf876b4e2705f4a1ecf42b.tar.gz
samba-f88b7a076be74a29a3bf876b4e2705f4a1ecf42b.tar.bz2
samba-f88b7a076be74a29a3bf876b4e2705f4a1ecf42b.zip
This is a large patch (sorry). Migrate from struct in_addr
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)
Diffstat (limited to 'source3')
-rw-r--r--source3/auth/auth_domain.c20
-rw-r--r--source3/auth/auth_server.c10
-rw-r--r--source3/client/client.c18
-rw-r--r--source3/include/ads.h2
-rw-r--r--source3/include/client.h2
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/include/smb.h4
-rw-r--r--source3/include/smb_macros.h5
-rw-r--r--source3/lib/interface.c14
-rw-r--r--source3/lib/util_sock.c206
-rw-r--r--source3/lib/util_str.c83
-rw-r--r--source3/libads/kerberos.c38
-rw-r--r--source3/libads/krb5_setpw.c28
-rw-r--r--source3/libads/ldap.c35
-rw-r--r--source3/libsmb/cliconnect.c152
-rw-r--r--source3/libsmb/clidfs.c20
-rw-r--r--source3/libsmb/clidgram.c27
-rw-r--r--source3/libsmb/clikrb5.c4
-rw-r--r--source3/libsmb/libsmbclient.c106
-rw-r--r--source3/libsmb/namecache.c156
-rw-r--r--source3/libsmb/namequery.c1126
-rw-r--r--source3/libsmb/namequery_dc.c75
-rw-r--r--source3/libsmb/nmblib.c15
-rw-r--r--source3/libsmb/passchange.c6
-rw-r--r--source3/libsmb/trusts_util.c6
-rw-r--r--source3/nmbd/nmbd.c65
-rw-r--r--source3/nmbd/nmbd_become_dmb.c2
-rw-r--r--source3/nmbd/nmbd_browsesync.c2
-rw-r--r--source3/nmbd/nmbd_lmhosts.c11
-rw-r--r--source3/nmbd/nmbd_namelistdb.c4
-rw-r--r--source3/nmbd/nmbd_nameregister.c2
-rw-r--r--source3/nmbd/nmbd_packets.c4
-rw-r--r--source3/nmbd/nmbd_subnetdb.c8
-rw-r--r--source3/nmbd/nmbd_synclists.c4
-rw-r--r--source3/nmbd/nmbd_winsserver.c24
-rw-r--r--source3/nsswitch/winbind_krb5_locator.c4
-rw-r--r--source3/nsswitch/wins.c16
-rw-r--r--source3/rpc_server/srv_netlog_nt.c6
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c30
-rw-r--r--source3/rpcclient/rpcclient.c46
-rw-r--r--source3/smbd/change_trust_pw.c6
-rw-r--r--source3/smbd/server.c169
-rw-r--r--source3/torture/locktest.c10
-rw-r--r--source3/torture/masktest.c10
-rw-r--r--source3/torture/torture.c10
-rw-r--r--source3/utils/net.c196
-rw-r--r--source3/utils/net.h2
-rw-r--r--source3/utils/net_ads.c36
-rw-r--r--source3/utils/net_lookup.c93
-rw-r--r--source3/utils/net_rpc.c30
-rw-r--r--source3/utils/net_rpc_join.c6
-rw-r--r--source3/utils/net_rpc_printer.c13
-rw-r--r--source3/utils/net_time.c14
-rw-r--r--source3/utils/netlookup.c10
-rw-r--r--source3/utils/nmblookup.c400
-rw-r--r--source3/utils/smbcacls.c15
-rw-r--r--source3/utils/smbcquotas.c15
-rw-r--r--source3/web/diagnose.c16
-rw-r--r--source3/winbindd/winbindd.h2
-rw-r--r--source3/winbindd/winbindd_ads.c18
-rw-r--r--source3/winbindd/winbindd_cm.c169
-rw-r--r--source3/winbindd/winbindd_rpc.c16
-rw-r--r--source3/winbindd/winbindd_util.c6
-rw-r--r--source3/winbindd/winbindd_wins.c74
64 files changed, 2235 insertions, 1489 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 72bdbab182..7cddabbbbd 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -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;
}
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c
index 815c1193d1..8b10be93fc 100644
--- a/source3/auth/auth_server.c
+++ b/source3/auth/auth_server.c
@@ -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);
diff --git a/source3/client/client.c b/source3/client/client.c
index f3d454ec4b..7561ecb6a3 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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':
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 37d09f1e42..a75eaf80fc 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -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;
diff --git a/source3/include/client.h b/source3/include/client.h
index 597348d162..c4669dbf2e 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -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;
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 0d51c3d049..fc9e43e55b 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -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);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 6d4effda5e..4c51acf6f4 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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;
};
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index aea429d2ea..9af63451b0 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -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
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 0696329fd6..49bbceceb7 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -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) ));
}
/****************************************************************************
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c6b1311cf5..2d784717b2 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -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;
@@ -275,6 +296,17 @@ void zero_ip_v4(struct in_addr *ip)
}
/*******************************************************************
+ 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)
@@ -434,6 +465,75 @@ char *print_sockaddr(char *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;
}
}
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 2fd22280a4..226bf826fb 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -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 char* ipstr_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.
**/
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 281ca2fd68..f259c21bdb 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -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);
diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c
index 73dffe7c1b..831a448847 100644
--- a/source3/libads/krb5_setpw.c
+++ b/source3/libads/krb5_setpw.c
@@ -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) {
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index f85d3cd7b0..0294c4a5b5 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -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);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 82cd6d6d13..826315ad7a 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -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;
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index f7bf8506fe..e1ca924b09 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -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;
}
/**********************************************************************
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 4fc9243b5b..9f6f4480c5 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -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 */
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index 4291834797..fb25e9e203 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -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);
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index 3b5818a015..d5bf1828c6 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -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);
diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
index b569100d94..6a675d2ef2 100644
--- a/source3/libsmb/namecache.c
+++ b/source3/libsmb/namecache.c
@@ -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/>.
*/
@@ -24,11 +25,10 @@
#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);
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 6585fd751c..34fe09b8c2 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -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;
diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c
index 16d8414b8f..0fa4b93990 100644
--- a/source3/libsmb/namequery_dc.c
+++ b/source3/libsmb/namequery_dc.c
@@ -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;
}
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 4d21258f99..7e152ab324 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -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);
}
/****************************************************************************
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index 83cfc3efbf..f5057ec73b 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -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) );
diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index e82d24426d..732dc78c75 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -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;
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index fe69587a4b..c6be4914da 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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);
diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c
index fb87927436..a0b2ef15f8 100644
--- a/source3/nmbd/nmbd_become_dmb.c
+++ b/source3/nmbd/nmbd_become_dmb.c
@@ -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) );
diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c
index e141b3e288..4effce0722 100644
--- a/source3/nmbd/nmbd_browsesync.c
+++ b/source3/nmbd/nmbd_browsesync.c
@@ -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 );
diff --git a/source3/nmbd/nmbd_lmhosts.c b/source3/nmbd/nmbd_lmhosts.c
index 8dda58e352..51e4858f32 100644
--- a/source3/nmbd/nmbd_lmhosts.c
+++ b/source3/nmbd/nmbd_lmhosts.c
@@ -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)) {
diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c
index 46a9830b25..ae5f766e66 100644
--- a/source3/nmbd/nmbd_namelistdb.c
+++ b/source3/nmbd/nmbd_namelistdb.c
@@ -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;
}
diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c
index b7f5a3d45b..edcf258519 100644
--- a/source3/nmbd/nmbd_nameregister.c
+++ b/source3/nmbd/nmbd_nameregister.c
@@ -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;
}
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index b19b1d3599..d49c8bab79 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -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;
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 39aa4577bb..d100ad482a 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -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) );
diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c
index df71e6db43..aaa56f9216 100644
--- a/source3/nmbd/nmbd_synclists.c
+++ b/source3/nmbd/nmbd_synclists.c
@@ -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;
}
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index 38962c2b39..70303af48b 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -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;
}
diff --git a/source3/nsswitch/winbind_krb5_locator.c b/source3/nsswitch/winbind_krb5_locator.c
index dc2664b67c..eef57ca2c0 100644
--- a/source3/nsswitch/winbind_krb5_locator.c
+++ b/source3/nsswitch/winbind_krb5_locator.c
@@ -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;
}
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
index 38bf3259f4..3401918f59 100644
--- a/source3/nsswitch/wins.c
+++ b/source3/nsswitch/wins.c
@@ -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);
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index b651fdaac3..13c0f38b74 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -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;
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 658ed99400..aba56c2d05 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -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;
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 27b2515169..2c285704de 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -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;
}
diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c
index eb26e56ac5..8ed0975781 100644
--- a/source3/smbd/change_trust_pw.c
+++ b/source3/smbd/change_trust_pw.c
@@ -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 */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index e52c2b3fba..61e20ce274 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -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 */
diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c
index 20fd49b3e1..f69f8bf48f 100644
--- a/source3/torture/locktest.c
+++ b/source3/torture/locktest.c
@@ -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;
diff --git a/source3/torture/masktest.c b/source3/torture/masktest.c
index 84c6e1c3a4..354607bb4e 100644
--- a/source3/torture/masktest.c
+++ b/source3/torture/masktest.c
@@ -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;
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index d684216232..8eb29d837d 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -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;
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 068118f476..fb82e76591 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -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;
diff --git a/source3/utils/net.h b/source3/utils/net.h
index 177c6d3601..2ffa4d77b1 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -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[];
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index bfbcbbde49..81b13ba76e 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -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 : "",
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index a1e8c1a6ed..f7af1f2bb3 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -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;
}
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index bf5e4c6b6d..5c5bb97bf6 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -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;
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index b32fa27284..0c25a53365 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -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:
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index 20821cd2e6..d14caad975 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -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;
diff --git a/source3/utils/net_time.c b/source3/utils/net_time.c
index 510807730e..7375206af6 100644
--- a/source3/utils/net_time.c
+++ b/source3/utils/net_time.c
@@ -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));
diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c
index 315a89d5a8..90f99e4c8b 100644
--- a/source3/utils/netlookup.c
+++ b/source3/utils/netlookup.c
@@ -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,
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c
index 1a26e81206..e68c786ce9 100644
--- a/source3/utils/nmblookup.c
+++ b/source3/utils/nmblookup.c
@@ -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);
}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index b8b29b44eb..d5bf9b96e6 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -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))) {
diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c
index a3d90f823b..f185caa50f 100644
--- a/source3/utils/smbcquotas.c
+++ b/source3/utils/smbcquotas.c
@@ -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))) {
diff --git a/source3/web/diagnose.c b/source3/web/diagnose.c
index df3b34dd16..221ce83f82 100644
--- a/source3/web/diagnose.c
+++ b/source3/web/diagnose.c
@@ -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;
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index e4b1396cac..454a4b9698 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -191,7 +191,7 @@ struct winbindd_domain {
/* A working DC */
fstring dcname;
- struct sockaddr_in dcaddr;
+ struct sockaddr_storage dcaddr;
/* Sequence number stuff */
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 3f3f06e3fd..6549c6d7d2 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -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;
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 055563d815..4c9ae0365f 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -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;
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index 7035f6bffb..55212a84b8 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -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;
}
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 8970c1faf9..5c8c8ea13d 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -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;
diff --git a/source3/winbindd/winbindd_wins.c b/source3/winbindd/winbindd_wins.c
index 2ee6f69b66..4a3d2682b6 100644
--- a/source3/winbindd/winbindd_wins.c
+++ b/source3/winbindd/winbindd_wins.c
@@ -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);