Subject: bin/17998: sshd utmpx handling is broken. utmpx.ut_id is required!
To: None <gnats-bugs@gnats.netbsd.org>
From: None <naoki@fukaumi.org>
List: netbsd-bugs
Date: 08/20/2002 16:24:19
>Number:         17998
>Category:       bin
>Synopsis:       sshd utmpx handling is broken. utmpx.ut_id is required!
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 20 00:25:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     FUKAUMI Naoki
>Release:        NetBSD 1.6F 20020812-1.6F
>Organization:
	FUKAUMI Naoki
>Environment:
System: NetBSD sparc64.naobsd.org 1.6F NetBSD 1.6F (GENERIC) #0: Wed Aug 14 16:13:18 JST 2002 root@sparc64.naobsd.org:/usr/obj/sparc64/sys/arch/sparc64/compile/GENERIC sparc64
Architecture: sparc64
Machine: sparc64
>Description:
	pututxline() calls getutxid(), and getutxid() uses utmpx.ut_id
	to search utmpx entries, and select a utmpx entry if matched.

	sshd call pututxline() in sshlogin.c::record_logout(), but sshd
	does not set utmpx.ut_id. so if you connect 2nd ssh connection,
	sshd will overwrite 1st sshd utmpx entry.
	(utmp is OK, so you can see missing utmpx entry in w(1) output)

	sshd should set ut_id correctly.

>How-To-Repeat:
	Login twice via sshd. strings(1) /var/run/utmpx.
	
>Fix:
	Special thanks to ume@freebsd.org, he advised me what's wrong,
	and how to fix this problem.
	(He found this problem on FreeBSD ported our utmpx code :)

	patch is below, idea from login(1), simplify.

	(openssh portable ver. in pkgsrc, will be OK, because configure
	 script will check ut_id in struct utmpx. See configure,
	 config.h and loginrec.c if you want to check it.)

--- src/crypto/dist/ssh/sshlogin.c.orig	Thu Aug  1 21:32:47 2002
+++ src/crypto/dist/ssh/sshlogin.c	Mon Aug 19 16:39:38 2002
@@ -165,6 +165,9 @@
 		ux.ut_tv = tv;
 		strncpy(ux.ut_name, user, sizeof(ux.ut_name));
 		strncpy(ux.ut_host, host, sizeof(ux.ut_host));
+		/* XXX: need ut_id, use last 4 char of ttyname */
+		strncpy(ux.ut_id, strchr(ttyname, '\0') - sizeof(ux.ut_id),
+		    sizeof(ux.ut_id));
 		/* XXX: It would be better if we had sockaddr_storage here */
 		memcpy(&ux.ut_ss, addr, sizeof(*addr));
 		if (pututxline(&ux) == NULL)
>Release-Note:
>Audit-Trail:
>Unformatted: