Commit 4bd95702 authored by Dan Peterson's avatar Dan Peterson Committed by Matthew Dempsky

net: expand nss myhostname fallback detection

Expand myhostname fallback detection to properly detect the local
hostname in addition to other supported special names and suffixes.

Fixes #17967

Change-Id: I1fe141fd9838b25886c08b6f2fd325e58be60457
Reviewed-on: https://go-review.googlesource.com/33550Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent c77e80df
...@@ -179,8 +179,6 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -179,8 +179,6 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
} }
} }
hasDot := byteIndex(hostname, '.') != -1
// Canonicalize the hostname by removing any trailing dot. // Canonicalize the hostname by removing any trailing dot.
if stringsHasSuffix(hostname, ".") { if stringsHasSuffix(hostname, ".") {
hostname = hostname[:len(hostname)-1] hostname = hostname[:len(hostname)-1]
...@@ -220,10 +218,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -220,10 +218,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
var first string var first string
for _, src := range srcs { for _, src := range srcs {
if src.source == "myhostname" { if src.source == "myhostname" {
if hostname == "" || hasDot { if isLocalhost(hostname) || isGateway(hostname) {
continue return fallbackOrder
} }
return fallbackOrder hn, err := getHostname()
if err != nil || stringsEqualFold(hostname, hn) {
return fallbackOrder
}
continue
} }
if src.source == "files" || src.source == "dns" { if src.source == "files" || src.source == "dns" {
if !src.standardCriteria() { if !src.standardCriteria() {
...@@ -306,3 +308,15 @@ func goDebugNetDNS() (dnsMode string, debugLevel int) { ...@@ -306,3 +308,15 @@ func goDebugNetDNS() (dnsMode string, debugLevel int) {
parsePart(goDebug) parsePart(goDebug)
return return
} }
// isLocalhost reports whether h should be considered a "localhost"
// name for the myhostname NSS module.
func isLocalhost(h string) bool {
return stringsEqualFold(h, "localhost") || stringsEqualFold(h, "localhost.localdomain") || stringsHasSuffixFold(h, ".localhost") || stringsHasSuffixFold(h, ".localhost.localdomain")
}
// isGateway reports whether h should be considered a "gateway"
// name for the myhostname NSS module.
func isGateway(h string) bool {
return stringsEqualFold(h, "gateway")
}
...@@ -13,8 +13,9 @@ import ( ...@@ -13,8 +13,9 @@ import (
) )
type nssHostTest struct { type nssHostTest struct {
host string host string
want hostLookupOrder localhost string
want hostLookupOrder
} }
func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) } func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) }
...@@ -42,8 +43,8 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -42,8 +43,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"foo.local", hostLookupCgo}, {"foo.local", "myhostname", hostLookupCgo},
{"google.com", hostLookupCgo}, {"google.com", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -54,7 +55,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -54,7 +55,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles}, {"x.com", "myhostname", hostLookupDNSFiles},
}, },
}, },
{ {
...@@ -65,7 +66,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -65,7 +66,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS}, {"x.com", "myhostname", hostLookupFilesDNS},
}, },
}, },
{ {
...@@ -75,11 +76,11 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -75,11 +76,11 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"foo.local", hostLookupCgo}, {"foo.local", "myhostname", hostLookupCgo},
{"foo.local.", hostLookupCgo}, {"foo.local.", "myhostname", hostLookupCgo},
{"foo.LOCAL", hostLookupCgo}, {"foo.LOCAL", "myhostname", hostLookupCgo},
{"foo.LOCAL.", hostLookupCgo}, {"foo.LOCAL.", "myhostname", hostLookupCgo},
{"google.com", hostLookupFilesDNS}, {"google.com", "myhostname", hostLookupFilesDNS},
}, },
}, },
{ {
...@@ -89,7 +90,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -89,7 +90,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: nssStr("foo: bar"), nss: nssStr("foo: bar"),
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
}, },
// On OpenBSD, no resolv.conf means no DNS. // On OpenBSD, no resolv.conf means no DNS.
{ {
...@@ -98,7 +99,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -98,7 +99,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{{"google.com", hostLookupFiles}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
}, },
{ {
name: "solaris_no_nsswitch", name: "solaris_no_nsswitch",
...@@ -107,7 +108,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -107,7 +108,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: &nssConf{err: os.ErrNotExist}, nss: &nssConf{err: os.ErrNotExist},
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
}, },
{ {
name: "openbsd_lookup_bind_file", name: "openbsd_lookup_bind_file",
...@@ -116,8 +117,8 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -116,8 +117,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: &dnsConfig{lookup: []string{"bind", "file"}}, resolv: &dnsConfig{lookup: []string{"bind", "file"}},
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"google.com", hostLookupDNSFiles}, {"google.com", "myhostname", hostLookupDNSFiles},
{"foo.local", hostLookupDNSFiles}, {"foo.local", "myhostname", hostLookupDNSFiles},
}, },
}, },
{ {
...@@ -126,7 +127,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -126,7 +127,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "bind"}}, resolv: &dnsConfig{lookup: []string{"file", "bind"}},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
}, },
{ {
name: "openbsd_lookup_bind", name: "openbsd_lookup_bind",
...@@ -134,7 +135,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -134,7 +135,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"bind"}}, resolv: &dnsConfig{lookup: []string{"bind"}},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupDNS}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNS}},
}, },
{ {
name: "openbsd_lookup_file", name: "openbsd_lookup_file",
...@@ -142,7 +143,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -142,7 +143,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file"}}, resolv: &dnsConfig{lookup: []string{"file"}},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupFiles}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
}, },
{ {
name: "openbsd_lookup_yp", name: "openbsd_lookup_yp",
...@@ -150,7 +151,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -150,7 +151,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}}, resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
}, },
{ {
name: "openbsd_lookup_two", name: "openbsd_lookup_two",
...@@ -158,7 +159,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -158,7 +159,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "foo"}}, resolv: &dnsConfig{lookup: []string{"file", "foo"}},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
}, },
{ {
name: "openbsd_lookup_empty", name: "openbsd_lookup_empty",
...@@ -166,7 +167,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -166,7 +167,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd", goos: "openbsd",
resolv: &dnsConfig{lookup: nil}, resolv: &dnsConfig{lookup: nil},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
}, },
// glibc lacking an nsswitch.conf, per // glibc lacking an nsswitch.conf, per
// http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html // http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html
...@@ -177,7 +178,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -177,7 +178,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: &nssConf{err: os.ErrNotExist}, nss: &nssConf{err: os.ErrNotExist},
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
}, },
{ {
name: "files_mdns_dns", name: "files_mdns_dns",
...@@ -186,8 +187,8 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -186,8 +187,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS}, {"x.com", "myhostname", hostLookupFilesDNS},
{"x.local", hostLookupCgo}, {"x.local", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -197,9 +198,9 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -197,9 +198,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupDNS}, {"x.com", "myhostname", hostLookupDNS},
{"x\\.com", hostLookupCgo}, // punt on weird glibc escape {"x\\.com", "myhostname", hostLookupCgo}, // punt on weird glibc escape
{"foo.com%en0", hostLookupCgo}, // and IPv6 zones {"foo.com%en0", "myhostname", hostLookupCgo}, // and IPv6 zones
}, },
}, },
{ {
...@@ -210,8 +211,8 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -210,8 +211,8 @@ func TestConfHostLookupOrder(t *testing.T) {
hasMDNSAllow: true, hasMDNSAllow: true,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupCgo}, {"x.com", "myhostname", hostLookupCgo},
{"x.local", hostLookupCgo}, {"x.local", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -221,9 +222,9 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -221,9 +222,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS}, {"x.com", "myhostname", hostLookupFilesDNS},
{"x", hostLookupFilesDNS}, {"x", "myhostname", hostLookupFilesDNS},
{"x.local", hostLookupCgo}, {"x.local", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -233,9 +234,9 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -233,9 +234,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles}, {"x.com", "myhostname", hostLookupDNSFiles},
{"x", hostLookupDNSFiles}, {"x", "myhostname", hostLookupDNSFiles},
{"x.local", hostLookupCgo}, {"x.local", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -245,7 +246,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -245,7 +246,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupCgo}, {"x.com", "myhostname", hostLookupCgo},
}, },
}, },
{ {
...@@ -255,9 +256,23 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -255,9 +256,23 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS}, {"x.com", "myhostname", hostLookupFilesDNS},
{"somehostname", hostLookupCgo}, {"myhostname", "myhostname", hostLookupCgo},
{"", hostLookupFilesDNS}, // Issue 13623 {"myHostname", "myhostname", hostLookupCgo},
{"myhostname.dot", "myhostname.dot", hostLookupCgo},
{"myHostname.dot", "myhostname.dot", hostLookupCgo},
{"gateway", "myhostname", hostLookupCgo},
{"Gateway", "myhostname", hostLookupCgo},
{"localhost", "myhostname", hostLookupCgo},
{"Localhost", "myhostname", hostLookupCgo},
{"anything.localhost", "myhostname", hostLookupCgo},
{"Anything.localhost", "myhostname", hostLookupCgo},
{"localhost.localdomain", "myhostname", hostLookupCgo},
{"Localhost.Localdomain", "myhostname", hostLookupCgo},
{"anything.localhost.localdomain", "myhostname", hostLookupCgo},
{"Anything.Localhost.Localdomain", "myhostname", hostLookupCgo},
{"somehostname", "myhostname", hostLookupFilesDNS},
{"", "myhostname", hostLookupFilesDNS}, // Issue 13623
}, },
}, },
{ {
...@@ -267,8 +282,9 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -267,8 +282,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS}, {"x.com", "myhostname", hostLookupFilesDNS},
{"somehostname", hostLookupCgo}, {"somehostname", "myhostname", hostLookupFilesDNS},
{"myhostname", "myhostname", hostLookupCgo},
}, },
}, },
// Debian Squeeze is just "dns,files", but lists all // Debian Squeeze is just "dns,files", but lists all
...@@ -282,8 +298,8 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -282,8 +298,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles}, {"x.com", "myhostname", hostLookupDNSFiles},
{"somehostname", hostLookupDNSFiles}, {"somehostname", "myhostname", hostLookupDNSFiles},
}, },
}, },
{ {
...@@ -292,7 +308,7 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -292,7 +308,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: nssStr("foo: bar"), nss: nssStr("foo: bar"),
resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true}, resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
}, },
hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
}, },
// Android should always use cgo. // Android should always use cgo.
{ {
...@@ -303,12 +319,18 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -303,12 +319,18 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf, resolv: defaultResolvConf,
}, },
hostTests: []nssHostTest{ hostTests: []nssHostTest{
{"x.com", hostLookupCgo}, {"x.com", "myhostname", hostLookupCgo},
}, },
}, },
} }
origGetHostname := getHostname
defer func() { getHostname = origGetHostname }()
for _, tt := range tests { for _, tt := range tests {
for _, ht := range tt.hostTests { for _, ht := range tt.hostTests {
getHostname = func() (string, error) { return ht.localhost, nil }
gotOrder := tt.c.hostLookupOrder(ht.host) gotOrder := tt.c.hostLookupOrder(ht.host)
if gotOrder != ht.want { if gotOrder != ht.want {
t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want) t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want)
......
...@@ -334,22 +334,28 @@ func stringsHasSuffix(s, suffix string) bool { ...@@ -334,22 +334,28 @@ func stringsHasSuffix(s, suffix string) bool {
// stringsHasSuffixFold reports whether s ends in suffix, // stringsHasSuffixFold reports whether s ends in suffix,
// ASCII-case-insensitively. // ASCII-case-insensitively.
func stringsHasSuffixFold(s, suffix string) bool { func stringsHasSuffixFold(s, suffix string) bool {
if len(suffix) > len(s) { return len(s) >= len(suffix) && stringsEqualFold(s[len(s)-len(suffix):], suffix)
}
// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
func stringsHasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
// stringsEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
// are equal, ASCII-case-insensitively.
func stringsEqualFold(s, t string) bool {
if len(s) != len(t) {
return false return false
} }
for i := 0; i < len(suffix); i++ { for i := 0; i < len(s); i++ {
if lowerASCII(suffix[i]) != lowerASCII(s[len(s)-len(suffix)+i]) { if lowerASCII(s[i]) != lowerASCII(t[i]) {
return false return false
} }
} }
return true return true
} }
// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
func stringsHasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
func readFull(r io.Reader) (all []byte, err error) { func readFull(r io.Reader) (all []byte, err error) {
buf := make([]byte, 1024) buf := make([]byte, 1024)
for { for {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment