Bug 68134

Summary: 'invalid hostname' displayed in w/who output
Product: Base System Reporter: fireball
Component: binAssignee: Robert Watson <rwatson>
Status: Closed FIXED    
Severity: Affects Only Me CC: fireball
Priority: Normal    
Version: 4.10-RELEASE   
Hardware: Any   
OS: Any   

Description fireball 2004-06-20 03:10:19 UTC
fireball@www[~]$ w
 3:50AM  up 6 days, 23:05, 2 users, load averages: 0.26, 0.06, 0.02
USER             TTY      FROM              LOGIN@  IDLE WHAT
fireball         p0       invalid hostname Sat04AM     - vi /tmp/pf.SSE0doNI
fireball         p1       invalid hostname  3:50AM     - w
fireball@www[~]$ who
fireball         ttyp0    Jun 19 04:07 (invalid hostname)
fireball         ttyp1    Jun 20 03:50 (invalid hostname)

I actually do have an IP of 192.168.0.xxx. Maybe is to mention that I am accessing the box (in the DMZ) through a NAT (ipnat),
and IMO it should be displaying the IP if it is unable to resolve the hostname correctly.

Fix: 

Too inexperienced with FreeBSD code (and not enough time to waste)...
Comment 1 Giorgos Keramidas 2004-06-24 19:09:03 UTC
On 2004-06-20 03:58, Jonas Nagel <fireball@zerouptime.ch> wrote:
> System:
> FreeBSD www.zerouptime.ch 4.10-RELEASE FreeBSD 4.10-RELEASE #0:
> Sat Jun 12 17:49:50 CEST 2004 root@www.zerouptime.ch:/usr/obj/usr/src/sys/WWW i386

> >Description:
>
> fireball@www[~]$ w
>  3:50AM  up 6 days, 23:05, 2 users, load averages: 0.26, 0.06, 0.02
> USER             TTY      FROM              LOGIN@  IDLE WHAT
> fireball         p0       invalid hostname Sat04AM     - vi /tmp/pf.SSE0doNI
> fireball         p1       invalid hostname  3:50AM     - w
> fireball@www[~]$ who
> fireball         ttyp0    Jun 19 04:07 (invalid hostname)
> fireball         ttyp1    Jun 20 03:50 (invalid hostname)
>
> I actually do have an IP of 192.168.0.xxx. Maybe is to mention that I
> am accessing the box (in the DMZ) through a NAT (ipnat), and IMO it
> should be displaying the IP if it is unable to resolve the hostname
> correctly.

I think it's probably revision 1.48 of src/usr.bin/w/w.c that you want.

: revision 1.48
: date: 2001/07/26 19:20:13;  author: brian;  state: Exp;  lines: +40 -41
: When -n is specified, don't attempt to turn hostnames found in utmp
: into addresses as we have no idea what address family they belong to.
:
: When -n is not specified, resolve IPv6 as well as IPv4 addresses found
: in the host field of utmp.  Use realhostname_sa() to resolve addresses
: (the old code was wrong).
:
: Rename ``x'' to ``x_suffix'' to avoid confusion.
:
: Hard code the host column width to 16 (against the imminent increase
: of UT_HOSTSIZE in utmp.h).

I don't have a 4.X installation nearby to test this & merge it though :(

- Giorgos
Comment 2 fireball 2004-06-26 13:47:09 UTC
Actually the Problem shows up both in 'who' and in 'w' and it should
never be displaying 'invalid hostname'.

If it's unable to resolve a hostname it should simply display the IP,
regardless of command line switches.

-- 
Jonas Nagel <fireball@zerouptime.ch>
Comment 3 Robert Watson freebsd_committer freebsd_triage 2005-01-03 22:56:28 UTC
Responsible Changed
From-To: freebsd-bugs->rwatson

Grab ownership of this PR.
Comment 4 Robert Watson freebsd_committer freebsd_triage 2005-01-03 23:01:16 UTC
On Mon, 3 Jan 2005, Robert Watson wrote:

> Synopsis: 'invalid hostname' displayed in w/who output

In FreeBSD 4.x, login called with a "-h" argument attempts to
sanitize/reduce the hostname before storing it in the utmp record for
later consumption by programs such as w(1), who(1) etc.  That
sanitization/reduction can fail resulting in the less appealing "invalid
hostname" string being left behind.  In FreeBSD 5.x, this sanitization is
not performed, and the caller is assumed to provide a useful and valid
string.  Could you do the following for me: 

- Tell me how it is you're logging into the machine -- telnet, rshd, sshd,
  etc.

- Show me what "dig -x" returns for the IP address you're logging in from.
  My suspicion is the name is simply longer than UT_HOSTSIZE.

My suspicion is that we should simply eliminate the sanitization, but I'd
like to understand what in the sanitization process is failing, and make
sure that we're looking at the right point in the code.  It could well be
that telnetd (or whatever is running login) is indeed passing in something
invalid, in which case that will also need fixing.  In particular, it's
likely we should always pass the IP address from the calling application,
and not a hostname, to avoid this and related difficulties.  You might try
the following patch to confirm that the "invalid string" string is
replaced by something else; this patch simply truncates rather than
replacing. 

Thanks,

Robert N M Watson


Index: login.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/login/login.c,v
retrieving revision 1.51.2.15
diff -u -r1.51.2.15 login.c
--- login.c	29 Apr 2003 14:10:41 -0000	1.51.2.15
+++ login.c	3 Jan 2005 23:03:45 -0000
@@ -217,34 +217,8 @@
 
 			trimdomain(optarg, UT_HOSTSIZE);
 
-			if (strlen(optarg) > UT_HOSTSIZE) {
-				struct addrinfo hints, *res;
-				int ga_err;
-				
-				memset(&hints, 0, sizeof(hints));
-				hints.ai_family = AF_UNSPEC;
-				ga_err = getaddrinfo(optarg, NULL, &hints,
-				    &res);
-				if (ga_err == 0) {
-					char hostbuf[MAXHOSTNAMELEN];
-
-					getnameinfo(res->ai_addr,
-					    res->ai_addrlen,
-					    hostbuf,
-					    sizeof(hostbuf), NULL, 0,
-					    NI_NUMERICHOST|
-					    NI_WITHSCOPEID);
-					optarg = strdup(hostbuf);
-					if (optarg == NULL) {
-						syslog(LOG_NOTICE,
-						    "strdup(): %m");
-						sleepexit(1);
-					}
-				} else
-					optarg = "invalid hostname";
-				if (res != NULL)
-					freeaddrinfo(res);
-			}
+			if (strlen(optarg) > UT_HOSTSIZE)
+				optarg[UT_HOSTSIZE-1] = '\0';
 			hostname = optarg;
 			break;
 		case 'p':
Comment 5 fireball 2005-01-04 16:27:19 UTC
> - Tell me how it is you're logging into the machine -- telnet, rshd, sshd,
>   etc.

I am logging in solely via ssh (v2) but I am enabling login(1) in the
sshd_config, so I can use the hosts.allow file.

> - Show me what "dig -x" returns for the IP address you're logging in from.
>   My suspicion is the name is simply longer than UT_HOSTSIZE.
>
> My suspicion is that we should simply eliminate the sanitization, but I'd
> like to understand what in the sanitization process is failing, and make
> sure that we're looking at the right point in the code.  It could well be
> that telnetd (or whatever is running login) is indeed passing in something
> invalid, in which case that will also need fixing.  In particular, it's
> likely we should always pass the IP address from the calling application,
> and not a hostname, to avoid this and related difficulties.  You might try
> the following patch to confirm that the "invalid string" string is
> replaced by something else; this patch simply truncates rather than
> replacing. 

Looks like your suspicion is correct:

fireball@www[~]$ uname -a
FreeBSD www.zerouptime.ch 4.10-RELEASE-p4 FreeBSD 4.10-RELEASE-p4 #0: Mon Nov 22 01:39:46 CET 2004    
root@www.zerouptime.ch:/usr/obj/usr/src/sys/WWW  i386

fireball@www[~]$ netstat -Sf inet |grep ssh 
tcp4       0     48  x.x.x.x.ssh        212.55.210.230.10157 ESTABLISHED

fireball@www[~]$ netstat -f inet |grep ssh
tcp4       0     48  www.ssh                hirtsrv04.hirt.c.10157 ESTABLISHED

fireball@www[~]$ w
 4:23PM  up 43 days, 14:25, 1 user, load averages: 0.00, 0.00, 0.00
USER             TTY      FROM              LOGIN@  IDLE WHAT
fireball         p0       invalid hostname  4:08PM     - w

fireball@www[~]$ dig -x 212.55.210.230
(...)
;; ANSWER SECTION:
230.210.55.212.in-addr.arpa.  1h49m9s IN PTR  hirtsrv04.hirt.ch.210.55.212.in-addr.arpa.
(...)


Now, as you pasted the relevant code, I noticed some logical error in
the coding:

// here it trims off the domain of the apparent fqdn hostname
			trimdomain(optarg, UT_HOSTSIZE);   

			if (strlen(optarg) > UT_HOSTSIZE) {
				struct addrinfo hints, *res;
				int ga_err;

				memset(&hints, 0, sizeof(hints));
				hints.ai_family = AF_UNSPEC;
/* here it tries to get the address from the hostname alone, and this
will hardly succeed (except it's a host within the the domain suffix
defined... */
				ga_err = getaddrinfo(optarg, NULL, &hints,
				    &res);
// ...therefore ga_err will almost never return 0...
				if (ga_err == 0) {
					char hostbuf[MAXHOSTNAMELEN];
// ...and will become 'invalid hostname':
-				} else
-					optarg = "invalid hostname";
-- 
Jonas Nagel <fireball@zerouptime.ch>
Comment 6 fireball 2006-06-10 13:25:14 UTC
In my up-to-date 4.x it's behaving correctly now.

Thank you very much.

-- 
Jonas Nagel <fireball@zerouptime.ch>
"Everything we humans say is either meaningless or meaningful. A lot of people never learn the difference." (El Reg)
Comment 7 Mark Linimon freebsd_committer freebsd_triage 2007-06-15 12:30:38 UTC
State Changed
From-To: open->closed

Submitter noted, some time ago, that this was fixed.