The branch, v3-6-test has been updated via 889cfcf Fix bug 8021 - Incorrect string termination in volume/volume_name for TRANS2-QUERY_FS_INFO/Info Volume. via 9648497 Fix is_myname_or_ipaddr() to be robust against strange DNS setups. from 17fe342 s3-epmapper: fix vars init and return errors
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 889cfcf35203b5ab82a8970ca9625701656e64f8 Author: Volodymyr Khomenko <volodymyr_khome...@dell.com> Date: Thu Mar 24 14:20:28 2011 -0700 Fix bug 8021 - Incorrect string termination in volume/volume_name for TRANS2-QUERY_FS_INFO/Info Volume. Autobuild-User: Jeremy Allison <j...@samba.org> Autobuild-Date: Thu Mar 24 23:07:09 CET 2011 on sn-devel-104 (cherry picked from commit 042aafb87df6c05877b8fc7ef0d44877689d860a) commit 9648497c91c13553d04e4be1e9133eea6df31220 Author: Jeremy Allison <j...@samba.org> Date: Thu Mar 24 12:11:02 2011 -0700 Fix is_myname_or_ipaddr() to be robust against strange DNS setups. If IPv6 DNS names are turned on, but Samba isn't configured to listen on an IPv6 interface, then is_myname_or_ipaddr() can return false on a valid DNS name that it should detect is our own. If the IPv6 addr is returned by preference, then looking at the first addr only causes is_myname_or_ipaddr() to fail. We need to look at all the addresses returned by the DNS lookup and check all of them against our interface list. This is an order N^2 lookup, but there shouldn't be enough addresses to make this a practical problem. Jeremy. (cherry picked from commit 5176a0b2af1bb16e530412faaa2f36108f312a03) ----------------------------------------------------------------------- Summary of changes: source3/lib/util_sock.c | 86 ++++++++++++++++++++++++++++++---------------- source3/smbd/trans2.c | 2 +- 2 files changed, 57 insertions(+), 31 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 3c97495..a2b7a49 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1582,13 +1582,46 @@ const char *get_mydnsfullname(void) } /************************************************************ + Is this my ip address ? +************************************************************/ + +static bool is_my_ipaddr(const char *ipaddr_str) +{ + struct sockaddr_storage ss; + struct iface_struct *nics; + int i, n; + + if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) { + return false; + } + + if (ismyaddr((struct sockaddr *)&ss)) { + return true; + } + + if (is_zero_addr(&ss) || + is_loopback_addr((struct sockaddr *)&ss)) { + return false; + } + + n = get_interfaces(talloc_tos(), &nics); + for (i=0; i<n; i++) { + if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) { + TALLOC_FREE(nics); + return true; + } + } + TALLOC_FREE(nics); + return false; +} + +/************************************************************ Is this my name ? ************************************************************/ bool is_myname_or_ipaddr(const char *s) { TALLOC_CTX *ctx = talloc_tos(); - char addr[INET6_ADDRSTRLEN]; char *name = NULL; const char *dnsname; char *servername = NULL; @@ -1636,45 +1669,38 @@ bool is_myname_or_ipaddr(const char *s) return true; } - /* Handle possible CNAME records - convert to an IP addr. */ - if (!is_ipaddress(servername)) { - /* Use DNS to resolve the name, but only the first address */ - struct sockaddr_storage ss; - if (interpret_string_addr(&ss, servername, 0)) { - print_sockaddr(addr, - sizeof(addr), - &ss); - servername = addr; - } - } - /* Maybe its an IP address? */ if (is_ipaddress(servername)) { - struct sockaddr_storage ss; - struct iface_struct *nics; - int i, n; - - if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) { - return false; - } + return is_my_ipaddr(servername); + } - if (ismyaddr((struct sockaddr *)&ss)) { - return true; - } + /* Handle possible CNAME records - convert to an IP addr. list. */ + { + /* Use DNS to resolve the name, check all addresses. */ + struct addrinfo *p = NULL; + struct addrinfo *res = NULL; - if (is_zero_addr(&ss) || - is_loopback_addr((struct sockaddr *)&ss)) { + if (!interpret_string_addr_internal(&res, + servername, + AI_ADDRCONFIG)) { return false; } - n = get_interfaces(talloc_tos(), &nics); - for (i=0; i<n; i++) { - if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) { - TALLOC_FREE(nics); + for (p = res; p; p = p->ai_next) { + char addr[INET6_ADDRSTRLEN]; + struct sockaddr_storage ss; + + ZERO_STRUCT(ss); + memcpy(&ss, p->ai_addr, p->ai_addrlen); + print_sockaddr(addr, + sizeof(addr), + &ss); + if (is_my_ipaddr(addr)) { + freeaddrinfo(res); return true; } } - TALLOC_FREE(nics); + freeaddrinfo(res); } /* No match */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 12cbc3b..693cf02 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3015,7 +3015,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u pdata, flags2, pdata+l2_vol_szVolLabel, vname, PTR_DIFF(end_data, pdata+l2_vol_szVolLabel), - STR_NOALIGN|STR_TERMINATE); + STR_NOALIGN); SCVAL(pdata,l2_vol_cch,len); data_len = l2_vol_szVolLabel + len; DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n", -- Samba Shared Repository