Handling of /etc/hosts is highly site- and admin- specific in
many more complex cases, and it's exceedingly hard and error-
prone for NetworkManager to handle all those cases. So remove
this functionality entirely. That's not a big loss, as it
turns out there's a much more elegant solution.
The only requirement is that the machine's hostname map back
to an IP address owned by the machine. That requirement can
be satisifed by nss-myhostname or even possibly the distro's
installer. If the user does not want nss-myhostname then it
can be uninstalled. Distros should use a "recommends" feature
in their packaging system so that the NetworkManager package
does *not* have a hard requirement on nss-myhostname. Thus
everyone is happy; things Just Work when nss-myhostname is
installed, but more advanced users can uninstall it and
customize /etc/hosts as they wish.
Another alternative is a dispatcher script that listents for
the 'hostname' event, and updates /etc/hosts according to the
administrator's preference.
config.h defines _GNU_SOURCE, which in turn defines the bits necessary
for kill, isblank, and isascii. So wherever we use those, we need
to make sure config.h is included.
Try to preserve custom hostnames (ie, anything not a localhost* variant,
the current hostname, or the previous hostname) when rewriting the
127.0.0.1/::1 localhost mapping lines.
NM-added mappings for active IP addresses were not getting properly
removed when the address disappeared of NM quit, because the bits
of code that determine whether or not /etc/hosts should change were
not taking the disappearance of the IP address into account, and
were leaving the file unchanged.
To fix that, if there is no default IP address, but there are NM-added
IP address entries in /etc/hosts, make sure we update /etc/hosts and
remove them.
If your hostname is 'foo.bar.baz' and your DNS server doesn't
actually reply to queries for 'foo.bar.baz' you can't just 'ping foo'
currently. While that may be somewhat of a misconfigured setup,
since we're already adding the domain part of the hostname to
/etc/resolv.conf we might as well add the short hostname to /etc/hosts
too so that ping works.
Otherwise glibc will count the localhost IPv6 (::1) mapping as
resolving to the IPv4 localhost mapping as well, so this:
127.0.0.1 localhost.localdomain localhost
::1 foobar localhost6.localdomain6 localhost6
192.168.1.2 fooar
causes a lookup of 'foobar' (or even just 'ping foobar') to resolve
to 127.0.0.1, even though the hostname is *not* listed on the
IPv4 localhost line. Apparently glibc just looks for the hostname
on any IPv4 or IPv6 localhost line.
We need to ensure that even if you don't have a routable IP address
for one of [IPv4, IPv6] that the hostname resolves to the localhost
address for that IP version, otherwise lots of stuff starts
breaking. But for the IP versions that you do have a routable IP
address, we want the hostname to map to that IP address too.
Instead of always mapping the current hostname to 127.0.0.1 or
whatever the user mapped it to manually, make sure the hostname
maps to the default device's IPv4 and IPv6 address if there's
a default device.
This helps out services that do a lookup on the machine hostname
to determine the IP address, which while a broken behavior (since
there are too many edge-cases) is pretty wide-spread and thus
we should support it.
In preparation for updating /etc/hosts to assign the current hostname
to the current IP address to allow programs that (somewhat incorrectly)
do DNS lookups on the machine's current hostname to find out its
IP address.
If the hostname was changed while NM wasn't running, and thus /etc/hosts
was out of sync with the new hostname, NM wouldn't make sure that
the new hostname was mapped in /etc/hosts. Make sure that happens
and add a bunch of testcases for /etc/hosts rewriting.