mirror of
https://github.com/samba-team/samba.git
synced 2025-02-22 05:57:43 +03:00
Added prefer_ipv4 bool parameter to resolve_name().
W2K3 DC's can have IPv6 addresses but won't serve krb5/ldap or cldap on those addresses. Make sure when we're asking for DC's we prefer IPv4. If you have an IPv6-only network this prioritizing code will be a no-op. And if you have a mixed network then you need to prioritize IPv4 due to W2K3 DC's. Jeremy.
This commit is contained in:
parent
571f20cd4d
commit
5d05d22999
@ -60,7 +60,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -3132,7 +3132,8 @@ NTSTATUS internal_resolve_name(const char *name,
|
||||
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,
|
||||
|
@ -192,29 +192,42 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
|
||||
{
|
||||
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"));
|
||||
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);
|
||||
}
|
||||
|
||||
if (!srv) {
|
||||
TALLOC_FREE(frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* this copes with inet_ntoa brokenness */
|
||||
|
||||
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;
|
||||
@ -267,10 +280,10 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
|
||||
sitename_store( cldap_reply.dns_domain, cldap_reply.client_site);
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
SAFE_FREE(srv);
|
||||
TALLOC_FREE(mem_ctx);
|
||||
|
||||
out:
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -615,8 +615,8 @@ SMBC_opendir_ctx(SMBCCTX *context,
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -675,7 +675,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
|
||||
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
|
||||
|
@ -439,12 +439,12 @@ static int addr_compare(const struct sockaddr *ss1,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -601,6 +601,38 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
|
||||
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.
|
||||
@ -1664,7 +1696,8 @@ NTSTATUS internal_resolve_name(const char *name,
|
||||
|
||||
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;
|
||||
@ -1681,6 +1714,19 @@ bool resolve_name(const char *name,
|
||||
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) &&
|
||||
@ -2056,7 +2102,7 @@ static NTSTATUS get_dc_list(const char *domain,
|
||||
|
||||
/* 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),
|
||||
@ -2086,6 +2132,13 @@ static NTSTATUS get_dc_list(const char *domain,
|
||||
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",
|
||||
|
@ -37,7 +37,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
|
||||
|
||||
*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;
|
||||
|
@ -3171,7 +3171,7 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
|
||||
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;
|
||||
}
|
||||
|
@ -2579,7 +2579,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
|
||||
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;
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ static bool netbios_session_retarget(const char *name, int name_type)
|
||||
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;
|
||||
|
@ -5633,7 +5633,7 @@ static bool run_tldap(int dummy)
|
||||
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;
|
||||
}
|
||||
|
@ -1655,7 +1655,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
|
||||
|
||||
/* 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,
|
||||
|
@ -53,7 +53,7 @@ static int net_lookup_host(struct net_context *c, int argc, const char **argv)
|
||||
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));
|
||||
@ -72,7 +72,7 @@ static void print_ldap_srvlist(struct dns_rr_srv *dclist, int numdcs )
|
||||
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
|
||||
|
@ -393,7 +393,7 @@ bool net_find_server(struct net_context *c,
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
@ -420,8 +420,8 @@ bool net_find_server(struct net_context *c,
|
||||
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;
|
||||
}
|
||||
@ -431,7 +431,7 @@ bool net_find_server(struct net_context *c,
|
||||
} 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;
|
||||
|
@ -232,7 +232,7 @@ static void start_filter(char *desthost)
|
||||
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);
|
||||
}
|
||||
|
@ -679,7 +679,7 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1467,7 +1467,7 @@ 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, 0x20)))
|
||||
&& (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
|
||||
{
|
||||
struct sockaddr_storage *addrs = NULL;
|
||||
int num_addrs = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user