diff -Nru mingetty-0.9.4.orig/mingetty.8 mingetty-0.9.4/mingetty.8 --- mingetty-0.9.4.orig/mingetty.8 Sun Apr 29 19:38:31 2001 +++ mingetty-0.9.4/mingetty.8 Sun Apr 29 19:40:47 2001 @@ -3,7 +3,7 @@ mingetty \- minimal getty for consoles .SH SYNOPSIS .B mingetty -[\-\-noclear] [\-\-long\-hostname] +[\-\-noclear] [\-\-long\-hostname] [\-\-autologin username] .I tty .PP .SH DESCRIPTION @@ -27,6 +27,41 @@ By default the hostname is only printed until the first dot. With this option enabled, the full text from gethostname() is shown. .TP +.B \-\-autologin username +Log the specified user onto the console (normally +.IR /dev/tty1 ) +when the system is first booted without prompting for a username or +password. +.IP +When the autologin option is supplied, +.B mingetty +will check that the controlling terminal is the console (normally +.IR /dev/tty1 ), +that a reasonable username has been supplied, and that this is the +first autologin request since the system has booted. If all of these +conditions have been met, a request for an unauthenticated login is +passed to the +.B login +program. Otherwise, a normal interactive login is performed. +.IP +The +.B login +program may deny the request for an unauthenticated login. Typically +this will happen when the user is root, has a UID of 0, or whenever a +normal interactive login would be denied due to the access +restrictions specified in the +.IR nologin , +.IR usertty , +or +.I securetty +files. +.IP +Only a single autologin request will be issued after a system boot. +If the automated login request is denied, or if the user logs out, +.B mingetty +will revert to performing normal interactive logins for all subsequent +login requests. +.TP .B \-\-mono Set terminal type to "linux-m" instead of default "linux" (for mono consoles) .TP @@ -73,7 +108,8 @@ .PP .SH FILES .IR /etc/issue , -.IR /var/run/utmp . +.IR /var/run/utmp , +.IR /var/log/autologin . .PP .SH "SEE ALSO" .BR mgetty (8), diff -Nru mingetty-0.9.4.orig/mingetty.c mingetty-0.9.4/mingetty.c --- mingetty-0.9.4.orig/mingetty.c Sun Apr 29 19:38:31 2001 +++ mingetty-0.9.4/mingetty.c Sun Apr 29 19:44:14 2001 @@ -17,7 +17,7 @@ * should be very reliable. For a modem getty, I'd also use nothing else * but mgetty. * - * Usage: mingetty [--noclear] tty + * Usage: mingetty [--noclear] [--autologin username] tty * Example entry in /etc/inittab: 1:123:respawn:/sbin/mingetty tty1 * * This program is free software; you can redistribute it and/or @@ -53,6 +53,20 @@ #endif #ifdef linux +/* Autologin stuff. Currently Linux-specific, since there's no + standard way of getting the system boot time. The kernel.h and the + sysinfo prototype are used to get the system uptime under Linux. */ +#include +int sysinfo(struct sysinfo *info); + +/* AUTO_LAST points to a timestamp file used to limit autologins to + one per system boot. */ +#define AUTO_LAST "/var/log/autologin" + +/* AUTO_TTY is the tty on which autologins will be accepted. If set + to an empty string, autologins will be accepted on any tty. */ +#define AUTO_TTY "tty1" + #include #define USE_SYSLOG #endif @@ -84,6 +98,8 @@ static int noclear = 0; /* Print the whole string of gethostname() instead of just until the next "." */ static int longhostname = 0; +/* If supplied, attempt an automatic login with this username. */ +static char *autologin_name = NULL; /* Set mono terminal type */ static int mono_term = 0; /* Log onto remote host */ @@ -398,6 +414,62 @@ return logname; } +/* + * autologin_ok -- returns 1 if it's okay to auto-login when: + * this login is from /dev/tty1; and + * there was a login name passed with the --autologin option; and + * the autologin_name contains only "nice" characters; and + * this is the first autologin attempt since the last boot; + * return 0 otherwise. + */ +static int autologin_ok(void) +{ + char c, *cp; + int stat_err, fd; + struct sysinfo info; + struct stat sbuf; + + /* Autologins are restricted to AUTO_TTY if non-empty. */ + if (AUTO_TTY[0] && strcmp(tty, AUTO_TTY)) + return 0; + + /* An all-alphanumeric autologin name must be supplied. */ + if (autologin_name == NULL || autologin_name[0] == '\0') + return 0; + for (cp = autologin_name; (c = *cp); cp++) + if (!isalnum(c) && c != '_') + return 0; + + /* Get the uptime in info.uptime, and the last autologin time + in sbuf.st_mtime. */ + sysinfo(&info); + stat_err = stat(AUTO_LAST, &sbuf); + + /* If a stat error other than "no such file" occurs, I don't + know what went wrong, so I'll proceed with caution by + denying the autologin request. */ + if (stat_err && errno != ENOENT) + return 0; + + /* If there's been an autologin granted since the last boot, + deny this and any subsequent attempts. Note that this test + is skipped if the AUTO_LAST file doesn't exist. */ + if (!stat_err && time(NULL) - info.uptime < sbuf.st_mtime) + return 0; + + /* Create the AUTO_LAST file. The mtime of this file provides + a persistent record of the last time that an autologin + request was granted. Deny the autologin request if either + the file open or file close fails. */ + if ((fd=open(AUTO_LAST, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) + return 0; + if (close(fd) != 0) + return 0; + + /* All tests are okay, so grant the autologin request. */ + return 1; +} + static void usage (void) { error ("usage: '%s tty' with e.g. tty=tty1", progname); @@ -406,6 +478,7 @@ static struct option const long_options[] = { { "noclear", no_argument, &noclear, 1}, { "long-hostname", no_argument, &longhostname, 1}, + { "autologin", required_argument, NULL, 'a'}, { "mono", no_argument, &mono_term, 1}, { "remote-host", required_argument, NULL, 2}, { "login-program", required_argument, NULL, 3}, @@ -441,6 +514,9 @@ strncpy(login_program, optarg, 1024); login_program[1023] = '\0'; break; + case 'a': + autologin_name = optarg; + break; default: usage (); } @@ -476,6 +552,9 @@ /* flush input and output queues, important for modems */ ioctl (0, TCFLSH, 2); + if (autologin_ok()) { + execl (_PATH_LOGIN, _PATH_LOGIN, "-f", autologin_name, NULL); + } else { while ((logname = get_logname ()) == 0); if (!remote_login) { @@ -487,6 +566,7 @@ strncpy(login_program, _PATH_SSH, 1024); execl (login_program, login_program, "-l", logname, remote_host, NULL); } + } error ("%s: can't exec %s: %s", login_program, tty, sys_errlist[errno]); exit (0); }