Bug 133224

Summary: hostname -s misleading
Product: [Fedora] Fedora Reporter: Jonathan Larmour <jifl-bugzilla>
Component: net-toolsAssignee: Radek Vokál <rvokal>
Status: CLOSED RAWHIDE QA Contact: Ben Levenson <benl>
Severity: medium Docs Contact:
Priority: medium    
Version: 3CC: alex, ecki, ludwig.nussel, mattdm, mbrandsma, rvokal, t8m
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: 1.60-57 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-10-18 08:54:41 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jonathan Larmour 2004-09-22 15:23:15 UTC
Description of problem:

With a pretty clean install of FC2, the installer creates an
/etc/hosts that looks like:
127.0.0.1 localhost.localdomain mypc.mydomain.com localhost mypc

Running "hostname" returns mypc.mydomain.com. However running
"hostname -s" returns "localhost" and "hostname -d" returns
"localdomain". Programs/scripts that use hostname -s to determine the
hostname for passing to other computers don't work very well.

In fact there are some programs like sendmail that have to have their
config munged because of things like this (they, like hostname -s, do
an NS lookup of the kernel hostname, and then a reverse NS lookup on
the returned IP to get the "canonical" name).

Now I know there's a reason for this: if a machine normally gets its
IP address from DHCP and is then disconnected from the network, it
shouldn't fail to be able to look up its own name. But surely there is
a better solution to this that doesn't involve "hostname -s" being
somewhat misleading?

Comment 1 Alex Schuilenburg 2004-09-22 15:30:07 UTC
Note that this problem disappears if /etc/host.conf is set to "order
bind,hosts" and a nameserver is reachable.  If a nameserver is
unavailable, the problem occurs again.  This means hostname -s/-d can
give two seperate values depending on whether DNS is working or not.


Comment 2 Radek Vokál 2004-09-23 07:59:35 UTC
If you want to get localhost.localdomain you have to use hostname -f
which displays short host name and the DNS domain name. Anyway I've
checked this bug on two different machines with same version of
net-tools and the results differs. Once I've seen
localhost.localdomain and on the second pc first alias (eg.
mypc.mydomain.com). "hostname -v" shows calling of gethostname()
function. My resume is that it's wrong setting of your DNCP server
which doesn't resolve your name correctly. 

Comment 3 Radek Vokál 2004-09-23 08:01:10 UTC
substitude DNCP with DHCP

Comment 4 Alex Schuilenburg 2004-09-23 09:41:25 UTC
Sorry, but you are wrong. Perhaps you misunderstood the problem.  It
has nothing to do with the DHCP server (which BTW does resolve the
name correctly) or whether we use DHCP at all.  DHCP was only
mentioned as a possible reason why you put mypc.mydomain.com as an
alias in /etc/hosts, but it is also clearly the wrong thing to do.

This is the errant behaviour:

[root@mypc root]# hostname
mypc.mydomain.com
[root@mypc root]# hostname -a
mypc.mydomain.com localhost mypc
[root@mypc root]# hostname -f
localhost.localdomain
[root@mypc root]# hostname -s
localhost
[root@mypc root]# hostname -d
localdomain
[root@mypc root]# hostname -v
gethostname()=`mypc.mydomain.com'
mypc.mydomain.com
[root@mypc root]# hostname -vf
gethostname()=`mypc.mydomain.com'
Resolving `mypc.mydomain.com' ...
Result: h_name=`localhost.localdomain'
Result: h_aliases=`mypc.mydomain.com'
Result: h_aliases=`localhost'
Result: h_aliases=`mypc.mydomain.com'
Result: h_addr_list=`127.0.0.1'
localhost.localdomain

The installer places mypc.mydomain.com in /etc/hosts as an alias for
127.0.0.1.  The result is that when you attempt to get the short name,
or fqdn, you end up with localhost and localhost.localdomain
respectively.  

An strace on hostname reveals that it is using the resolv library,
consulting /etc/nsswitch (i.e. hosts: files dns) and /etc/host.conf
(i.e. order hosts,bind) to determine the host and domain names.

If you force resolv to use a DNS server (order bind,hosts in
/etc/host.conf, hosts: dns files in /etc/nsswitch.conf), or even just
make mypc.mydomain.com the primary for 127.0.0.1 and
localhost.localdomain the alias in /etc/hosts, you get the correct and
expected behaviour (i.e. no appearance of localhost or localdomain in
any of the above commands).

Placing mypc.mydomain.com as an alias in /etc/hosts is what is causing
the errant behaviour. Make the changes to /etc/nsswitch.conf,
/etc/host.conf and /etc/hosts and see for yourself.

Comment 5 Jonathan Larmour 2004-09-23 10:07:37 UTC
What Alex said. It's nothing to do with the DHCP server, so reopening.

Comment 6 Tomas Mraz 2004-09-23 10:51:49 UTC
I think that the problem isn't with the functionality of hostname -s
but with the actual entry in /etc/hosts which is written by anaconda
and system-config-network.

For the hostname to be meaningful it has to resolve to the actual IP
address on the network you have set up. So the /etc/hosts should look
like this:

127.0.0.1 localhost.localdomain localhost
123.45.67.89 mypc.mydomain.com mypc

Substitute real IP above.
Then everything will work fine. This bug should get reassigned to
anaconda or system-config-network.



Comment 7 Jonathan Larmour 2004-09-23 11:01:11 UTC
Yes feel free to reassign the component if you think that's appropriate.

Of course the /etc/hosts can look like you suggest, but only if you
know the IP address, which is what I was referring to right at the
start: you won't know this for DHCP which is probably why
anaconda/system-config-network puts the host name against 127.0.0.1.

I'm not convinced, but perhaps system-config-network (or whatever)
should only put the hostname against 127.0.0.1 if we're using DHCP,
and then the DHCP _client_ should rewrite /etc/hosts when it gets a
lease? Would that be the "correct" fix?



Comment 8 Alex Schuilenburg 2004-09-23 11:22:00 UTC
If hostname is to appear in /etc/hosts against 127.0.0.1, then it
should be the primary one to produce the correct behaviour for
hostname et al.

However, who knows what this solution will break if you make the
primary entry for 127.0.0.1 something other than localhost.

The proper solution IMHO would be to add *nothing* against 127.0.0.1
(leaving it well alone as localhost.localdoman localhost) and only add
a seperate entry for the hostname with the IP address obtained via
DHCP, if you are using DHCP. This is obviously is only to catch
instances when the host is disconnected from a network after obtaining
its address via DHCP or DNS/NIS/etc is not working.

Comment 9 Radek Vokál 2004-09-23 11:57:45 UTC
Tomas is right about correct settings of /etc/hosts. Anyway it seems,
that system-config-network doesn't like this syntax and when the
hostname is changed it also rewrites /etc/hosts

[rvokal@garfield devel]$ cat /etc/hosts
127.0.0.1       localhost.localdomain   localhost
192.168.1.13    garfield

[rvokal@garfield devel]$ system-config-network
--> hostname changed from garfield to garfield-new <---

[rvokal@garfield devel]$ cat /etc/hosts
127.0.0.1       localhost.localdomain   garfield-new       localhost

So the correct /etc/hosts file should look like 

[rvokal@garfield devel]$ cat /etc/hosts
127.0.0.1       localhost.localdomain   localhost
192.168.1.13    garfield.mydomain       garfield

Reassigning this bug to system-config-network for additional comments.
In case of first /etc/hosts file the hosts are not resolved in
system-config-network hosts tab which I think is correct behaviour.
Anyway changing the hosthame affects only first line of /etc/hosts


Comment 10 Jonathan Larmour 2004-09-23 13:01:39 UTC
Alex: I agree about the separate entry for the IP address when
obtained via DHCP, which is what I was also saying. But you have to
also deal with the case of the machine not having a DHCP lease or not
being on a network. The hostname has to map to _some_ address, and so
that has to be 127.0.0.1.


Comment 11 Mitchell Brandsma 2004-10-14 03:05:32 UTC
I've got related problems with hostname -s on EL3.  It's not the 
localhost line specifically, rather it's how hostname works (badly).  
Firstly, "hostname" always returns what the hostname was last set to, 
regardless of whatever's in the hosts file.  If the short name is not 
requested, I reliably get "hostname.domain.com", and it doesn't open 
any files!  So why does it not do what it says in the manual:
       -s, --short
              Display the short host name. This is the host name cut 
at the first dot.

hostname without -s appears to get the entire returned string from 
uname's structure.  With that, instead of "cutting at the first dot" 
it uses a completely different method.  That's a bug to me.  Here's a 
sequence I can repeat.  Note the results of the second hostname -s vs 
without the -s! :

With this /etc/hosts (which does not change during the tests):
172.1.2.3 hostname.domain.com hostname hostname1.domain.com hostname1
127.0.0.1 localhost.localdomain localhost

[root@hostname1 /]# hostname
hostname1.domain.com
[root@hostname1 /]# hostname -s
hostname
[root@hostname1 /]# hostname hostname2.domain.com
[root@hostname1 /]# hostname
hostname2.domain.com
[root@hostname1 /]# hostname -s
hostname: Unknown host
[root@hostname1 /]# hostname hostname1.domain.com 
[root@hostname1 /]# hostname
hostname1.domain.com
[root@hostname1 /]# hostname -s
hostname

An strace of hostname vs hostname -s reveals an interesting story...

"hostname" performs a bunch of system calls (it does not read any 
files apart from opening libraries), ending with a uname followed by 
the write...

"hostname -s" interrogates the /etc/resolv.conf, nsswitch.conf, 
host.conf, and hosts files on top of that, and gets the answer from 
the hosts file itself...

This is IMHO inconsistent and thus flawed.

Comment 12 Harald Hoyer 2004-10-14 08:45:01 UTC
If you change the hostname in s-c-network it does not automatically
change your /etc/hosts! 
If the new hostname does not resolv to a IP address through DNS or
/etc/hosts, it is added to localhost.

Comment 13 Mitchell Brandsma 2004-10-28 01:05:34 UTC
I still do not see why two so very different methods are used for two 
methods accessing one piece of information.

It's like asking you your full name, and you tell me what you've 
always known from when you first learnt how to say it and write it 
down.  Then I ask you your first name, and you have to look yourself 
up in the reverse phone directory and HOPE that you're in it.  It 
makes no sense.

The point is, the hostname command DOES NOT OPEN /etc/hosts when you 
don't ask for the full version.  But it does when you want the 
short.  This is inconsistent, and quite frankly, wrong.

Comment 14 Matthew Miller 2005-04-26 15:15:02 UTC
Fedora Core 2 is now maintained by the Fedora Legacy project for
security updates only. If this problem is a security issue, please
reopen and reassign to the Fedora Legacy product. If it is not a
security issue and hasn't been resolved in the current FC3 updates or
in the FC4 test release, reopen and change the version to match.

Comment 15 Jonathan Larmour 2005-04-26 20:47:18 UTC
I can confirm that the issue still exists in a fully up-to-date FC3.

The steps to reproduce are identical to previously, but I will repeat them
anyway: here I took a working system with hostname dargo. Using
system-config-network I changed the hostname (on the DNS tab) to dargon, which
doesn't exist in DNS. After doing that, I could do the following:
[root@dargo etc]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1	localhost.localdomain	dargon	localhost
[root@dargo etc]# hostname
dargon
[root@dargo etc]# hostname -s
localhost
[root@dargo etc]# hostname -a
dargon localhost
[root@dargo etc]# hostname -d
localdomain

So just as bogus as before.


Comment 16 Matthew Miller 2005-04-26 20:54:39 UTC
Moving to fc3 as per comment #15.

For what it's worth, if you do a net install via anaconda, you get a correct
/etc/hosts file:

127.0.0.1               localhost.localdomain localhost
128.197.20.188          evol.bu.edu evol


Comment 17 Radek Vokál 2005-10-18 08:54:41 UTC
I've added a note to hostname(1) about -s option describing the way it resolvs
the  hostname. I think this is enought to close this problem, changing the
current `hostname` behaviour doesn't make much sense to me. 

Comment 18 Alex Schuilenburg 2005-10-18 12:47:23 UTC
I don't know when the errant behaviour started, but it needs to be fixed and
made consistent with the behaviour of hostname on other *NIX implementations.
Documenting the problem is not an adequate solution or resolution to this
problem. Hence I request this bug be re-opened. 

Comment 19 Mitchell Brandsma 2005-10-19 02:47:06 UTC
I must agree with Alex' statement.  Please don't redefine bad program behaviour 
as normal by changing documentation.  Amongst other things, this unexpected 
behaviour breaks some (admittedly obscure) aspects of Oracle applications.  We 
settled for an ugly workaround while it was required.  Of course, it's not just 
broken in FC, it's broken in AS/EL too.

Comment 20 Bernd Eckenfels 2008-05-07 00:52:27 UTC
Hello,

hostname -s, hostname -f and hostname -d currently all work by looking up uname
with gethostbyname, and then working on the first result: -s uses first part, -f
all and -d the last part. hostname -a prints all aliases, not only the first.

hostname with no option returns uname without looking it up first (use -v to see
what hostname does).

So as I am upstream maintainer, I will at least fix the man page. However Ludwig
Nussel from Suse asked me, if it is preffered to have hostname -s use uname and
strip off a domain (since most new systems use a FQDN uname). This would avoid
the dns lookups and some confusion, act as documented (somewhat). But I am not
sure if the changed behaviour this might cause problems? (However i think
hostname -s is currently eighter wrong or the same has "hostname sans domain")

All users of "hostname -s" not wanting the DNS lookup could of course use 

bash> h=$(hostname); h=${h/.*/); echo shorthostname=$h

instead of changing the hostname semantic.

upstream:
https://cvs.berlios.de/cgi-bin/viewcvs.cgi/net-tools/net-tools/hostname.c?rev=1.12&content-type=text/vnd.viewcvs-markup