}
strupper_m(desthost);
- if(!resolve_name( desthost, &dest_ss, 0x20)) {
+ if(!resolve_name( desthost, &dest_ss, 0x20, false)) {
DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
continue;
}
const char *resolve_order);
bool resolve_name(const char *name,
struct sockaddr_storage *return_ss,
- int name_type);
+ int name_type,
+ bool prefer_ipv4);
NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
const char *name,
int name_type,
{
char *srv;
struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
- TALLOC_CTX *mem_ctx = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
bool ret = false;
if (!server || !*server) {
+ TALLOC_FREE(frame);
return False;
}
- DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
- server, ads->server.realm));
+ if (!is_ipaddress(server)) {
+ struct sockaddr_storage ss;
+ char addr[INET6_ADDRSTRLEN];
- mem_ctx = talloc_init("ads_try_connect");
- if (!mem_ctx) {
- DEBUG(0,("out of memory\n"));
- return false;
+ if (!resolve_name(server, &ss, 0x20, true)) {
+ DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
+ server ));
+ TALLOC_FREE(frame);
+ return false;
+ }
+ print_sockaddr(addr, sizeof(addr), &ss);
+ srv = talloc_strdup(frame, addr);
+ } else {
+ /* this copes with inet_ntoa brokenness */
+ srv = talloc_strdup(frame, server);
}
- /* this copes with inet_ntoa brokenness */
+ if (!srv) {
+ TALLOC_FREE(frame);
+ return false;
+ }
- srv = SMB_STRDUP(server);
+ DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
+ srv, ads->server.realm));
ZERO_STRUCT( cldap_reply );
- if ( !ads_cldap_netlogon_5(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) {
+ if ( !ads_cldap_netlogon_5(frame, srv, ads->server.realm, &cldap_reply ) ) {
DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
ret = false;
goto out;
sitename_store( cldap_reply.dns_domain, cldap_reply.client_site);
ret = true;
+
out:
- SAFE_FREE(srv);
- TALLOC_FREE(mem_ctx);
+ TALLOC_FREE(frame);
return ret;
}
*/
if (!srv &&
!is_ipaddress(server) &&
- (resolve_name(server, &rem_ss, 0x1d) || /* LMB */
- resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
+ (resolve_name(server, &rem_ss, 0x1d, false) || /* LMB */
+ resolve_name(server, &rem_ss, 0x1b, false) )) { /* DMB */
fstring buserver;
return NULL;
}
} else if (srv ||
- (resolve_name(server, &rem_ss, 0x20))) {
+ (resolve_name(server, &rem_ss, 0x20, false))) {
/*
* If we hadn't found the server, get one now
int num_interfaces = iface_count();
int i;
- /* Sort IPv6 addresses first. */
+ /* Sort IPv4 addresses first. */
if (ss1->sa_family != ss2->sa_family) {
if (ss2->sa_family == AF_INET) {
- return -1;
- } else {
return 1;
+ } else {
+ return -1;
}
}
return count;
}
+static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count);
+ int i, j;
+
+ if (iplist_new == NULL) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ j = 0;
+
+ /* Copy IPv4 first. */
+ for (i = 0; i < count; i++) {
+ if (iplist[i].ss.ss_family == AF_INET) {
+ iplist_new[j++] = iplist[i];
+ }
+ }
+
+ /* Copy IPv6. */
+ for (i = 0; i < count; i++) {
+ if (iplist[i].ss.ss_family != AF_INET) {
+ iplist_new[j++] = iplist[i];
+ }
+ }
+
+ memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
+ TALLOC_FREE(frame);
+ return true;
+}
+
/****************************************************************************
Do a netbios name query to find someones IP.
Returns an array of IP addresses or NULL if none.
bool resolve_name(const char *name,
struct sockaddr_storage *return_ss,
- int name_type)
+ int name_type,
+ bool prefer_ipv4)
{
struct ip_service *ss_list = NULL;
char *sitename = NULL;
lp_name_resolve_order()))) {
int i;
+ if (prefer_ipv4) {
+ for (i=0; i<count; i++) {
+ if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
+ !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
+ (ss_list[i].ss.ss_family == AF_INET)) {
+ *return_ss = ss_list[i].ss;
+ SAFE_FREE(ss_list);
+ SAFE_FREE(sitename);
+ return True;
+ }
+ }
+ }
+
/* only return valid addresses for TCP connections */
for (i=0; i<count; i++) {
if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
/* explicit lookup; resolve_name() will
* handle names & IP addresses */
- if (resolve_name( name, &name_ss, 0x20 )) {
+ if (resolve_name( name, &name_ss, 0x20, true )) {
char addr[INET6_ADDRSTRLEN];
print_sockaddr(addr,
sizeof(addr),
local_count );
}
+ /* For DC's we always prioritize IPv4 due to W2K3 not
+ * supporting LDAP, KRB5 or CLDAP over IPv6. */
+
+ if (local_count && return_iplist) {
+ prioritize_ipv4_list(return_iplist, local_count);
+ }
+
if ( DEBUGLEVEL >= 4 ) {
DEBUG(4,("get_dc_list: returning %d ip addresses "
"in an %sordered list\n",
*err_str = NULL;
- if(!resolve_name( remote_machine, &ss, 0x20)) {
+ if(!resolve_name( remote_machine, &ss, 0x20, false)) {
if (asprintf(err_str, "Unable to find an IP address for machine "
"%s.\n", remote_machine) == -1) {
*err_str = NULL;
result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
- if (!resolve_name(host, &addr, 0)) {
+ if (!resolve_name(host, &addr, 0, false)) {
status = NT_STATUS_NOT_FOUND;
goto fail;
}
struct sockaddr_storage rm_addr;
if ( is_zero_addr((struct sockaddr *)client_ss) ) {
- if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
+ if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
return false;
}
sscanf(p, "%x", &retarget_type);
}
- ret = resolve_name(retarget, &retarget_addr, retarget_type);
+ ret = resolve_name(retarget, &retarget_addr, retarget_type, false);
if (!ret) {
DEBUG(10, ("could not resolve %s\n", retarget));
goto fail;
struct tevent_req *req;
char *basedn;
- if (!resolve_name(host, &addr, 0)) {
+ if (!resolve_name(host, &addr, 0, false)) {
d_printf("could not find host %s\n", host);
return false;
}
/* Get printer data from SPOOLSS */
- resolve_name(servername, &server_ss, 0x20);
+ resolve_name(servername, &server_ss, 0x20, false);
nt_status = cli_full_connection(&cli, global_myname(), servername,
&server_ss, 0,
sscanf(++p,"%x",&name_type);
}
- if (!resolve_name(name, &ss, name_type)) {
+ if (!resolve_name(name, &ss, name_type, false)) {
/* 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));
int i;
for ( i=0; i<numdcs; i++ ) {
- if (resolve_name(dclist[i].hostname, &ss, 0x20) ) {
+ if (resolve_name(dclist[i].hostname, &ss, 0x20, true) ) {
char addr[INET6_ADDRSTRLEN];
print_sockaddr(addr, sizeof(addr), &ss);
#ifdef HAVE_IPV6
}
} else if (*server_name) {
/* resolve the IP address */
- if (!resolve_name(*server_name, server_ss, 0x20)) {
+ if (!resolve_name(*server_name, server_ss, 0x20, false)) {
DEBUG(1,("Unable to resolve server name\n"));
return false;
}
struct sockaddr_storage msbrow_ss;
char addr[INET6_ADDRSTRLEN];
- /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
- if (!resolve_name(d, &msbrow_ss, 0x1B)) {
+ /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */
+ if (!resolve_name(d, &msbrow_ss, 0x1B, false)) {
DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
return false;
}
} else if (flags & NET_FLAGS_MASTER) {
struct sockaddr_storage brow_ss;
char addr[INET6_ADDRSTRLEN];
- if (!resolve_name(d, &brow_ss, 0x1D)) {
+ if (!resolve_name(d, &brow_ss, 0x1D, false)) {
/* go looking for workgroups */
DEBUG(1,("Unable to resolve master browser via name lookup\n"));
return false;
d_printf("listen failed\n");
}
- if (!resolve_name(desthost, &dest_ss, 0x20)) {
+ if (!resolve_name(desthost, &dest_ss, 0x20, false)) {
d_printf("Unable to resolve host %s\n", desthost);
exit(1);
}
DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
- if (!resolve_name(dcname, dc_ss, 0x20)) {
+ if (!resolve_name(dcname, dc_ss, 0x20, true)) {
return False;
}
if (*domain->dcname
&& NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
- && (resolve_name(domain->dcname, &domain->dcaddr, 0x20)))
+ && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
{
struct sockaddr_storage *addrs = NULL;
int num_addrs = 0;