Sulogin: enforce reconnection of stdin/stdout/stderr if a device

was specified.
This commit is contained in:
Werner Fink 2011-07-26 10:21:13 +00:00
parent 3cb95c8371
commit eddea371ca
4 changed files with 39 additions and 13 deletions

View File

@ -28,6 +28,8 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low
otherwise initialize SELinux and load the policy. Patch from otherwise initialize SELinux and load the policy. Patch from
Petter Reinholdtsen. Petter Reinholdtsen.
* Make quotes visible in example of the manual page of fstab-decode * 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 ] [ Petter Reinholdtsen ]
* Next release will be 2.89dsf. * Next release will be 2.89dsf.

View File

@ -225,17 +225,23 @@ void consalloc(char * name)
* /dev/console if but only if /dev/console is used. On Linux * /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 * this can be more than one device, e.g. a serial line as well
* as a virtual console as well as a simple printer. * 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__ #ifdef __linux__
char *attrib, *cmdline; char *attrib, *cmdline;
FILE *fc; FILE *fc;
#endif #endif
if (!device || *device == '\0') if (!device || *device == '\0')
fd = dup(fallback); 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) { if (fd >= 0) {
DIR *dir; DIR *dir;
@ -250,6 +256,9 @@ void detect_consoles(const char *device, int fallback)
goto fallback; goto fallback;
} }
comparedev = st.st_rdev; comparedev = st.st_rdev;
if (ret && (fstat(fallback, &st) < 0 || comparedev != st.st_rdev))
dup2(fd, fallback);
#ifdef __linux__ #ifdef __linux__
/* /*
* Check if the device detection for Linux system console should be used. * 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); closedir(dir);
if (!consoles) if (!consoles)
goto fallback; goto fallback;
return; return ret;
} }
#ifdef __linux__ #ifdef __linux__
console: console:
@ -325,7 +334,7 @@ console:
} }
closedir(dir); closedir(dir);
fclose(fc); fclose(fc);
return; return ret;
} }
/* /*
* Detection of devices used for Linux system console using * Detection of devices used for Linux system console using
@ -363,7 +372,7 @@ console:
free(attrib); free(attrib);
if (!consoles) if (!consoles)
goto fallback; goto fallback;
return; return ret;
} }
/* /*
@ -471,12 +480,12 @@ console:
if (consoles) { if (consoles) {
if (!device || *device == '\0') if (!device || *device == '\0')
consoles->fd = fallback; consoles->fd = fallback;
return; return ret;
} }
#endif #endif
goto fallback; goto fallback;
} }
return; return ret;
} }
#endif /* __linux __ */ #endif /* __linux __ */
fallback: fallback:
@ -494,4 +503,5 @@ fallback:
if (consoles) if (consoles)
consoles->fd = fallback; consoles->fd = fallback;
} }
return ret;
} }

View File

@ -45,4 +45,4 @@ struct console {
struct console *next; struct console *next;
}; };
extern struct console *consoles; extern struct console *consoles;
extern void detect_consoles(const char *, int); extern int detect_consoles(const char *, int);

View File

@ -841,6 +841,7 @@ int main(int argc, char **argv)
char *tty = NULL; char *tty = NULL;
struct passwd *pwd; struct passwd *pwd;
int c, status = 0; int c, status = 0;
int reconnect = 0;
int opt_e = 0; int opt_e = 0;
struct console *con; struct console *con;
pid_t pid; 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; opterr = 0;
while((c = getopt(argc, argv, "ept:")) != EOF) switch(c) { 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); 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) if (optind < argc)
tty = argv[optind]; tty = argv[optind];
@ -892,9 +893,10 @@ int main(int argc, char **argv)
tty = getenv("CONSOLE"); 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 * Should not happen
@ -906,6 +908,17 @@ int main(int argc, char **argv)
exit(1); 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. * Get the root password.
*/ */
@ -967,6 +980,7 @@ int main(int argc, char **argv)
break; break;
} }
fprintf(stderr, "Login incorrect.\n\r"); fprintf(stderr, "Login incorrect.\n\r");
sleep(3);
} }
if (alarm_rised) { if (alarm_rised) {
tcfinal(con); tcfinal(con);