From eddea371cae949cd964fbf3919447a40ad04af27 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Tue, 26 Jul 2011 10:21:13 +0000 Subject: [PATCH] Sulogin: enforce reconnection of stdin/stdout/stderr if a device was specified. --- doc/Changelog | 2 ++ src/consoles.c | 26 ++++++++++++++++++-------- src/consoles.h | 2 +- src/sulogin.c | 22 ++++++++++++++++++---- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 1116bd9..dc99219 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -28,6 +28,8 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low otherwise initialize SELinux and load the policy. Patch from Petter Reinholdtsen. * Make quotes visible in example of the manual page of fstab-decode + * Sulogin: enforce reconnection of stdin/stdout/stderr if a device + was specified. [ Petter Reinholdtsen ] * Next release will be 2.89dsf. diff --git a/src/consoles.c b/src/consoles.c index d3e6c00..7b3be9b 100644 --- a/src/consoles.c +++ b/src/consoles.c @@ -225,17 +225,23 @@ void consalloc(char * name) * /dev/console if but only if /dev/console is used. On Linux * this can be more than one device, e.g. a serial line as well * as a virtual console as well as a simple printer. + * + * Returns 1 if stdout and stderr should be reconnected and 0 + * otherwise. */ -void detect_consoles(const char *device, int fallback) +int detect_consoles(const char *device, int fallback) { - int fd; + int fd, ret = 0; #ifdef __linux__ char *attrib, *cmdline; FILE *fc; #endif if (!device || *device == '\0') fd = dup(fallback); - else fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); + else { + fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); + ret = 1; + } if (fd >= 0) { DIR *dir; @@ -250,6 +256,9 @@ void detect_consoles(const char *device, int fallback) goto fallback; } comparedev = st.st_rdev; + + if (ret && (fstat(fallback, &st) < 0 || comparedev != st.st_rdev)) + dup2(fd, fallback); #ifdef __linux__ /* * Check if the device detection for Linux system console should be used. @@ -294,7 +303,7 @@ void detect_consoles(const char *device, int fallback) closedir(dir); if (!consoles) goto fallback; - return; + return ret; } #ifdef __linux__ console: @@ -325,7 +334,7 @@ console: } closedir(dir); fclose(fc); - return; + return ret; } /* * Detection of devices used for Linux system console using @@ -363,7 +372,7 @@ console: free(attrib); if (!consoles) goto fallback; - return; + return ret; } /* @@ -471,12 +480,12 @@ console: if (consoles) { if (!device || *device == '\0') consoles->fd = fallback; - return; + return ret; } #endif goto fallback; } - return; + return ret; } #endif /* __linux __ */ fallback: @@ -494,4 +503,5 @@ fallback: if (consoles) consoles->fd = fallback; } + return ret; } diff --git a/src/consoles.h b/src/consoles.h index 024a12a..c669eb2 100644 --- a/src/consoles.h +++ b/src/consoles.h @@ -45,4 +45,4 @@ struct console { struct console *next; }; extern struct console *consoles; -extern void detect_consoles(const char *, int); +extern int detect_consoles(const char *, int); diff --git a/src/sulogin.c b/src/sulogin.c index 99451c2..b1bd75a 100644 --- a/src/sulogin.c +++ b/src/sulogin.c @@ -841,6 +841,7 @@ int main(int argc, char **argv) char *tty = NULL; struct passwd *pwd; int c, status = 0; + int reconnect = 0; int opt_e = 0; struct console *con; pid_t pid; @@ -854,7 +855,7 @@ int main(int argc, char **argv) } /* - * See if we have a timeout flag. + * See if we have a timeout flag. */ opterr = 0; while((c = getopt(argc, argv, "ept:")) != EOF) switch(c) { @@ -884,7 +885,7 @@ int main(int argc, char **argv) saved_sighup = signal(SIGHUP, SIG_IGN); /* - * See if we need to open an other tty device. + * See if we need to open an other tty device. */ if (optind < argc) tty = argv[optind]; @@ -892,9 +893,10 @@ int main(int argc, char **argv) tty = getenv("CONSOLE"); /* - * Detect possible consoles, use stdin as fallback. + * Detect possible consoles, use stdin as fallback. + * If an optional tty is given, reconnect it to stdin. */ - detect_consoles(tty, 0); + reconnect = detect_consoles(tty, 0); /* * Should not happen @@ -906,6 +908,17 @@ int main(int argc, char **argv) exit(1); } + /* + * If previous stdin was not the speified tty and therefore reconnected + * to the specified tty also reconnect stdout and stderr. + */ + if (reconnect) { + if (isatty(1) == 0) + dup2(0, 1); + if (isatty(2) == 0) + dup2(0, 2); + } + /* * Get the root password. */ @@ -967,6 +980,7 @@ int main(int argc, char **argv) break; } fprintf(stderr, "Login incorrect.\n\r"); + sleep(3); } if (alarm_rised) { tcfinal(con);