From fc6c9b2a5d5168b16a4dc89913b8da40080c4db4d77ab18cabb810215674893a Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Tue, 26 Jul 2011 12:13:53 +0000 Subject: [PATCH] . OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=130 --- sysvinit-2.88dsf-multiple-sulogin.patch | 160 ++++++++++++++++-------- sysvinit.changes | 7 ++ 2 files changed, 113 insertions(+), 54 deletions(-) diff --git a/sysvinit-2.88dsf-multiple-sulogin.patch b/sysvinit-2.88dsf-multiple-sulogin.patch index cd30a2f..f8f38a7 100644 --- a/sysvinit-2.88dsf-multiple-sulogin.patch +++ b/sysvinit-2.88dsf-multiple-sulogin.patch @@ -1,5 +1,5 @@ --- src/sulogin.c -+++ src/sulogin.c 2011-05-19 10:47:11.783926103 +0000 ++++ src/sulogin.c 2011-07-26 14:01:55.543926269 +0200 @@ -28,8 +28,10 @@ * */ @@ -350,7 +350,7 @@ */ if (p == NULL) { - fprintf(stderr, "%s: no entry for root\n", F_PASSWD); -+ fprintf(stderr, "%s: no entry for root\n\r", F_PASSWD); ++ fprintf(stderr, "sulogin: %s: no entry for root\n\r", F_PASSWD); return &pwd; } if (valid(pwd.pw_passwd)) return &pwd; @@ -359,21 +359,21 @@ strcpy(pwd.pw_passwd, ""); if ((fp = fopen(F_SHADOW, "r")) == NULL) { - fprintf(stderr, "%s: root password garbled\n", F_PASSWD); -+ fprintf(stderr, "%s: root password garbled\n\r", F_PASSWD); ++ fprintf(stderr, "sulogin: %s: root password garbled\n\r", F_PASSWD); return &pwd; } while((p = fgets(sline, 256, fp)) != NULL) { -@@ -333,67 +499,212 @@ struct passwd *getrootpwent(int try_manu +@@ -333,67 +499,215 @@ struct passwd *getrootpwent(int try_manu * NULL it, and return. */ if (p == NULL) { - fprintf(stderr, "%s: no entry for root\n", F_SHADOW); -+ fprintf(stderr, "%s: no entry for root\n\r", F_SHADOW); ++ fprintf(stderr, "sulogin: %s: no entry for root\n\r", F_SHADOW); strcpy(pwd.pw_passwd, ""); } if (!valid(pwd.pw_passwd)) { - fprintf(stderr, "%s: root password garbled\n", F_SHADOW); -+ fprintf(stderr, "%s: root password garbled\n\r", F_SHADOW); ++ fprintf(stderr, "sulogin: %s: root password garbled\n\r", F_SHADOW); strcpy(pwd.pw_passwd, ""); } return &pwd; } @@ -532,7 +532,7 @@ + cp->eol = *ptr = '\0'; + + eightbit = ((con->flags & CON_SERIAL) == 0 || (tty.c_cflag & (PARODD|PARENB)) == 0); -+ while (cp->eol == 0) { ++ while (cp->eol == '\0') { + if (read(fd, &c, 1) < 1) { + if (errno == EINTR || errno == EAGAIN) { + usleep(1000); @@ -565,6 +565,9 @@ + } + + switch (ascval) { ++ case 0: ++ *ptr = '\0'; ++ goto quit; + case CR: + case NL: + *ptr = '\0'; @@ -607,19 +610,19 @@ return ret; } -@@ -411,7 +722,10 @@ void sushell(struct passwd *pwd) +@@ -411,7 +725,10 @@ void sushell(struct passwd *pwd) /* * Set directory and shell. */ - (void)chdir(pwd->pw_dir); + if (chdir(pwd->pw_dir) < 0) { + if (chdir("/") < 0) -+ fprintf(stderr, "Change of working directory failed: %m\n"); ++ fprintf(stderr, "sulogin: change of working directory failed: %m\n\r"); + } if ((p = getenv("SUSHELL")) != NULL) sushell = p; else if ((p = getenv("sushell")) != NULL) -@@ -431,7 +745,8 @@ void sushell(struct passwd *pwd) +@@ -431,7 +748,8 @@ void sushell(struct passwd *pwd) /* * Set some important environment variables. */ @@ -629,7 +632,7 @@ setenv("HOME", home, 1); setenv("LOGNAME", "root", 1); setenv("USER", "root", 1); -@@ -445,17 +760,18 @@ void sushell(struct passwd *pwd) +@@ -445,17 +763,18 @@ void sushell(struct passwd *pwd) signal(SIGINT, saved_sigint); signal(SIGTSTP, saved_sigtstp); signal(SIGQUIT, saved_sigquit); @@ -651,13 +654,13 @@ + if (getseuserbyname("root", &seuser, &level) == 0) + if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { + if (setexeccon(scon) != 0) -+ fprintf(stderr, "setexeccon failed\n\r"); ++ fprintf(stderr, "sulogin: setexeccon failed\n\r"); + freecon(scon); + } free(seuser); free(level); } -@@ -474,20 +790,68 @@ void sushell(struct passwd *pwd) +@@ -474,23 +793,72 @@ void sushell(struct passwd *pwd) perror(STATICSH); } @@ -715,6 +718,7 @@ struct passwd *pwd; - int c, fd = -1; + int c, status = 0; ++ int reconnect = 0; int opt_e = 0; - pid_t pid, pgrp, ppgrp, ttypgrp; + struct console *con; @@ -729,8 +733,12 @@ + } /* - * See if we have a timeout flag. -@@ -510,115 +874,138 @@ 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) { +@@ -510,115 +878,151 @@ int main(int argc, char **argv) } if (geteuid() != 0) { @@ -746,10 +754,10 @@ saved_sigquit = signal(SIGQUIT, SIG_IGN); saved_sigtstp = signal(SIGTSTP, SIG_IGN); - if (optind < argc) tty = argv[optind]; +- +- if (tty || (tty = getenv("CONSOLE"))) { + saved_sighup = signal(SIGHUP, SIG_IGN); -- if (tty || (tty = getenv("CONSOLE"))) { -- - if ((fd = open(tty, O_RDWR)) < 0) { - perror(tty); - fd = dup(0); @@ -760,7 +768,7 @@ - close(fd); - } else { + /* -+ * 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]; @@ -783,9 +791,10 @@ - setsid(); - } + /* -+ * 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); - signal(SIGHUP, SIG_IGN); - if (ttypgrp > 0) @@ -829,7 +838,17 @@ -#if defined(SANE_TIO) && (SANE_TIO == 1) - fixtty(); -#endif -- ++ /* ++ * 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. */ @@ -906,10 +925,11 @@ + signal(SIGINT, SIG_IGN); + + if (failed) { -+ fprintf(stderr, "Can not execute su shell.\n\r"); ++ fprintf(stderr, "sulogin: can not execute su shell.\n\r"); + break; + } + fprintf(stderr, "Login incorrect.\n\r"); ++ sleep(3); + } + if (alarm_rised) { + tcfinal(con); @@ -956,7 +976,7 @@ return 0; } --- src/consoles.c -+++ src/consoles.c 2011-04-01 10:37:59.827926346 +0000 ++++ src/consoles.c 2011-07-26 12:17:30.139926327 +0200 @@ -27,9 +27,21 @@ #include #include @@ -979,7 +999,7 @@ #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) # ifndef typeof # define typeof __typeof__ -@@ -43,8 +55,93 @@ +@@ -43,8 +55,100 @@ struct console *consoles; @@ -1013,8 +1033,8 @@ + +#ifdef __linux__ +/* -+ * Read and determine active attribute for tty, -+ * the caller has to free the result. ++ * Read and determine active attribute for tty below ++ * /sys/class/tty, the caller has to free the result. + */ +static +__attribute__((__malloc__)) @@ -1037,7 +1057,10 @@ + return ret; +} + -+/* Read and determine device attribute for tty */ ++/* ++ * Read and determine device attribute for tty below ++ * /sys/class/tty. ++ */ +static +dev_t devattr(const char *tty) +{ @@ -1064,6 +1087,10 @@ +} +#endif /* __linux__ */ + ++/* ++ * Search below /dev for the characer device in ++ * the local `dev_t comparedev' variable. ++ */ static dev_t comparedev; -static char* scandev(DIR *dir) +static @@ -1074,11 +1101,14 @@ { char *name = (char*)0; struct dirent *dent; -@@ -69,41 +166,310 @@ static char* scandev(DIR *dir) +@@ -69,41 +173,335 @@ static char* scandev(DIR *dir) return name; } -void detect_consoles(void) ++/* ++ * Default control characters for an unknown terminal line. ++ */ +static +struct chardata initcp = { + CERASE, @@ -1087,6 +1117,12 @@ + 0 +}; + ++/* ++ * Allocate an aligned `struct console' memory area, ++ * initialize its default values, and append it to ++ * the global linked list. ++ */ ++ +static int concount; /* Counter for console IDs */ + +static @@ -1117,9 +1153,18 @@ + consoles->next = tail; +} + -+void detect_consoles(const char *device, int fallback) ++/* ++ * Try to detect the real device(s) used for the system console ++ * /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. ++ */ ++int detect_consoles(const char *device, int fallback) +{ -+ int fd; ++ int fd, ret = 0; +#ifdef __linux__ + char *attrib, *cmdline; FILE *fc; @@ -1127,7 +1172,10 @@ +#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; @@ -1142,6 +1190,9 @@ + 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. @@ -1186,7 +1237,7 @@ + closedir(dir); + if (!consoles) + goto fallback; -+ return; ++ return ret; + } +#ifdef __linux__ +console: @@ -1220,7 +1271,7 @@ + } + closedir(dir); + fclose(fc); -+ return; ++ return ret; + } + /* + * Detection of devices used for Linux system console using @@ -1229,7 +1280,7 @@ + if ((attrib = actattr("console"))) { + char *words = attrib, *token; + DIR *dir; - ++ + dir = opendir("/dev"); + if (!dir) { + free(attrib); @@ -1248,7 +1299,7 @@ + comparedev = devattr(tmp); + free(tmp); + } -+ + + name = scandev(dir); if (!name) continue; @@ -1258,8 +1309,10 @@ + free(attrib); + if (!consoles) + goto fallback; -+ return; -+ ++ return ret; + +- if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) +- perror("memory allocation"); + } + /* + * Detection of devices used for Linux system console using @@ -1268,7 +1321,9 @@ + if ((cmdline = oneline("/proc/cmdline"))) { + char *words= cmdline, *token; + DIR *dir; -+ + +- tail->next = (struct console*)0; +- tail->tty = name; + dir = opendir("/dev"); + if (!dir) { + free(cmdline); @@ -1282,23 +1337,23 @@ + struct stat st; +#endif + char *colon, *name; -+ + +- if (!consoles) +- consoles = tail; +- else +- consoles->next = tail; + if (*token != 'c') + continue; + + if (strncmp(token, "console=", 8) != 0) + continue; + token += 8; - -- if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) -- perror("memory allocation"); ++ + if (strcmp(token, "brl") == 0) + token += 4; + if ((colon = strchr(token, ','))) + *colon = '\0'; - -- tail->next = (struct console*)0; -- tail->tty = name; ++ + if (asprintf(&name, "/dev/%s", token) < 0) + continue; + @@ -1328,11 +1383,7 @@ + } +#endif + close(fd); - -- if (!consoles) -- consoles = tail; -- else -- consoles->next = tail; ++ + name = scandev(dir); + if (!name) + continue; @@ -1376,12 +1427,12 @@ + if (consoles) { + if (!device || *device == '\0') + consoles->fd = fallback; -+ return; ++ return ret; + } +#endif + goto fallback; + } -+ return; ++ return ret; + } +#endif /* __linux __ */ +fallback: @@ -1399,9 +1450,10 @@ + if (consoles) + consoles->fd = fallback; } ++ return ret; } --- src/consoles.h -+++ src/consoles.h 2011-04-01 09:25:53.402826920 +0000 ++++ src/consoles.h 2011-07-26 11:07:40.273249830 +0200 @@ -21,13 +21,28 @@ * Author: Werner Fink */ @@ -1434,7 +1486,7 @@ }; extern struct console *consoles; -extern void detect_consoles(void); -+extern void detect_consoles(const char *, int); ++extern int detect_consoles(const char *, int); --- src/Makefile +++ src/Makefile 2010-03-23 15:11:12.000000000 +0000 @@ -112,7 +112,7 @@ utmpdump: utmpdump.o diff --git a/sysvinit.changes b/sysvinit.changes index 2834ccf..e1a4abc 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Jul 26 12:13:18 UTC 2011 - werner@suse.de + +- Sulogin: enforce reconnection of stdin/stdout/stderr if a device + was specified. +- Sulogin: if zero is read at reading the passwd guess it's done. + ------------------------------------------------------------------- Tue Jun 28 08:36:54 UTC 2011 - aj@suse.de