Subject: bin/36294: login(1) -- inconsistent exit behavior on EOF
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <zeurkous@nichten.info>
List: netbsd-bugs
Date: 05/08/2007 06:15:01
>Number:         36294
>Category:       bin
>Synopsis:       login(1) -- inconsistent exit behavior on EOF
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue May 08 06:15:00 +0000 2007
>Originator:     De Zeurkous
>Release:        NetBSD-3.1
>Organization:
The Mare Project
>Environment:
System: NetBSD lichee.nichten.info 3.1 NetBSD 3.1 (GENERIC) #0: Tue Oct 31 04:27:07 UTC 2006 builds@b0.netbsd.org:/home/builds/ab/netbsd-3-1-RELEASE/i386/200610302053Z-obj/home/builds/ab/netbsd-3-1-RELEASE/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
login(1) always returns zero on EOF, even though the login fails and is subsequently logged as such. As a side effect of this inconsistent behavior, a loop which repeatedly invokes login(1) lacks a convenient escape.
>How-To-Repeat:
Run login(1), input EOF, check exit status.
>Fix:
Since changing the exit code will probably break compatibility, I suggest a new '-e' option for login(1) that makes it return non-zero under these circumstances (and possibly similar ones in the future):

diff -u -r1.94 login.c
--- src/usr.bin/login/login.c   17 Jan 2007 00:21:43 -0000      1.94
+++ src/usr.bin/login/login.c   7 May 2007 23:09:12 -0000
@@ -167,7 +167,7 @@
        extern char **environ;
        struct group *gr;
        struct stat st;
-       int ask, ch, cnt, fflag, hflag, pflag, sflag, quietlog, rootlogin, rval;
+       int ask, ch, cnt, fflag, hflag, pflag, sflag, eflag, quietlog, rootlogin, rval;
        int Fflag;
        uid_t uid, saved_uid;
        gid_t saved_gid, saved_gids[NGROUPS_MAX];
@@ -212,6 +212,7 @@
         * -a in addition to -h, a server may supply -a to pass the actual
         *    server address.
         * -s is used to force use of S/Key or equivalent.
+        * -e is used to return non-zero on EOF.
         */
        domain = NULL;
        if (gethostname(localhost, sizeof(localhost)) < 0)
@@ -220,7 +221,7 @@
                domain = strchr(localhost, '.');
        localhost[sizeof(localhost) - 1] = '\0';

-       Fflag = fflag = hflag = pflag = sflag = 0;
+       Fflag = fflag = hflag = pflag = sflag = eflag = 0;
        have_ss = 0;
 #ifdef KERBEROS5
        have_forward = 0;
@@ -260,6 +261,9 @@
                case 's':
                        sflag = 1;
                        break;
+               case 'e':
+                       eflag = 1;
+                       break;
                default:
                case '?':
                        usage();
@@ -798,6 +802,7 @@
                for (p = nbuf; (ch = getchar()) != '\n'; ) {
                        if (ch == EOF) {
                                badlogin(username);
+                               if ( eflag == 1 ) exit(1);
                                exit(0);
                        }
                        if (p < nbuf + (NBUFSIZ - 1))