Dr. Werner Fink 2011-07-26 12:13:53 +00:00 committed by Git OBS Bridge
parent e62cfce59e
commit fc6c9b2a5d
2 changed files with 113 additions and 54 deletions

View File

@ -1,5 +1,5 @@
--- src/sulogin.c --- 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 @@ @@ -28,8 +28,10 @@
* *
*/ */
@ -350,7 +350,7 @@
*/ */
if (p == NULL) { if (p == NULL) {
- fprintf(stderr, "%s: no entry for root\n", F_PASSWD); - 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; return &pwd;
} }
if (valid(pwd.pw_passwd)) return &pwd; if (valid(pwd.pw_passwd)) return &pwd;
@ -359,21 +359,21 @@
strcpy(pwd.pw_passwd, ""); strcpy(pwd.pw_passwd, "");
if ((fp = fopen(F_SHADOW, "r")) == NULL) { if ((fp = fopen(F_SHADOW, "r")) == NULL) {
- fprintf(stderr, "%s: root password garbled\n", F_PASSWD); - 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; return &pwd;
} }
while((p = fgets(sline, 256, fp)) != NULL) { 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. * NULL it, and return.
*/ */
if (p == NULL) { if (p == NULL) {
- fprintf(stderr, "%s: no entry for root\n", F_SHADOW); - 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, ""); strcpy(pwd.pw_passwd, "");
} }
if (!valid(pwd.pw_passwd)) { if (!valid(pwd.pw_passwd)) {
- fprintf(stderr, "%s: root password garbled\n", F_SHADOW); - 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, ""); } strcpy(pwd.pw_passwd, ""); }
return &pwd; return &pwd;
} }
@ -532,7 +532,7 @@
+ cp->eol = *ptr = '\0'; + cp->eol = *ptr = '\0';
+ +
+ eightbit = ((con->flags & CON_SERIAL) == 0 || (tty.c_cflag & (PARODD|PARENB)) == 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 (read(fd, &c, 1) < 1) {
+ if (errno == EINTR || errno == EAGAIN) { + if (errno == EINTR || errno == EAGAIN) {
+ usleep(1000); + usleep(1000);
@ -565,6 +565,9 @@
+ } + }
+ +
+ switch (ascval) { + switch (ascval) {
+ case 0:
+ *ptr = '\0';
+ goto quit;
+ case CR: + case CR:
+ case NL: + case NL:
+ *ptr = '\0'; + *ptr = '\0';
@ -607,19 +610,19 @@
return ret; return ret;
} }
@@ -411,7 +722,10 @@ void sushell(struct passwd *pwd) @@ -411,7 +725,10 @@ void sushell(struct passwd *pwd)
/* /*
* Set directory and shell. * Set directory and shell.
*/ */
- (void)chdir(pwd->pw_dir); - (void)chdir(pwd->pw_dir);
+ if (chdir(pwd->pw_dir) < 0) { + if (chdir(pwd->pw_dir) < 0) {
+ if (chdir("/") < 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) if ((p = getenv("SUSHELL")) != NULL)
sushell = p; sushell = p;
else if ((p = getenv("sushell")) != NULL) 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. * Set some important environment variables.
*/ */
@ -629,7 +632,7 @@
setenv("HOME", home, 1); setenv("HOME", home, 1);
setenv("LOGNAME", "root", 1); setenv("LOGNAME", "root", 1);
setenv("USER", "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(SIGINT, saved_sigint);
signal(SIGTSTP, saved_sigtstp); signal(SIGTSTP, saved_sigtstp);
signal(SIGQUIT, saved_sigquit); signal(SIGQUIT, saved_sigquit);
@ -651,13 +654,13 @@
+ if (getseuserbyname("root", &seuser, &level) == 0) + if (getseuserbyname("root", &seuser, &level) == 0)
+ if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { + if (get_default_context_with_level(seuser, level, 0, &scon) == 0) {
+ if (setexeccon(scon) != 0) + if (setexeccon(scon) != 0)
+ fprintf(stderr, "setexeccon failed\n\r"); + fprintf(stderr, "sulogin: setexeccon failed\n\r");
+ freecon(scon); + freecon(scon);
+ } + }
free(seuser); free(seuser);
free(level); free(level);
} }
@@ -474,20 +790,68 @@ void sushell(struct passwd *pwd) @@ -474,23 +793,72 @@ void sushell(struct passwd *pwd)
perror(STATICSH); perror(STATICSH);
} }
@ -715,6 +718,7 @@
struct passwd *pwd; struct passwd *pwd;
- int c, fd = -1; - int c, fd = -1;
+ int c, status = 0; + int c, status = 0;
+ int reconnect = 0;
int opt_e = 0; int opt_e = 0;
- pid_t pid, pgrp, ppgrp, ttypgrp; - pid_t pid, pgrp, ppgrp, ttypgrp;
+ struct console *con; + struct console *con;
@ -729,8 +733,12 @@
+ } + }
/* /*
* See if we have a timeout flag. - * See if we have a timeout flag.
@@ -510,115 +874,138 @@ int main(int argc, char **argv) + * 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) { if (geteuid() != 0) {
@ -746,10 +754,10 @@
saved_sigquit = signal(SIGQUIT, SIG_IGN); saved_sigquit = signal(SIGQUIT, SIG_IGN);
saved_sigtstp = signal(SIGTSTP, SIG_IGN); saved_sigtstp = signal(SIGTSTP, SIG_IGN);
- if (optind < argc) tty = argv[optind]; - if (optind < argc) tty = argv[optind];
-
- if (tty || (tty = getenv("CONSOLE"))) {
+ saved_sighup = signal(SIGHUP, SIG_IGN); + saved_sighup = signal(SIGHUP, SIG_IGN);
- if (tty || (tty = getenv("CONSOLE"))) {
-
- if ((fd = open(tty, O_RDWR)) < 0) { - if ((fd = open(tty, O_RDWR)) < 0) {
- perror(tty); - perror(tty);
- fd = dup(0); - fd = dup(0);
@ -784,8 +792,9 @@
- } - }
+ /* + /*
+ * 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); - signal(SIGHUP, SIG_IGN);
- if (ttypgrp > 0) - if (ttypgrp > 0)
@ -829,7 +838,17 @@
-#if defined(SANE_TIO) && (SANE_TIO == 1) -#if defined(SANE_TIO) && (SANE_TIO == 1)
- fixtty(); - fixtty();
-#endif -#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. * Get the root password.
*/ */
@ -906,10 +925,11 @@
+ signal(SIGINT, SIG_IGN); + signal(SIGINT, SIG_IGN);
+ +
+ if (failed) { + if (failed) {
+ fprintf(stderr, "Can not execute su shell.\n\r"); + fprintf(stderr, "sulogin: can not execute su shell.\n\r");
+ 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);
@ -956,7 +976,7 @@
return 0; return 0;
} }
--- src/consoles.c --- 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 @@ @@ -27,9 +27,21 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@ -979,7 +999,7 @@
#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
# ifndef typeof # ifndef typeof
# define typeof __typeof__ # define typeof __typeof__
@@ -43,8 +55,93 @@ @@ -43,8 +55,100 @@
struct console *consoles; struct console *consoles;
@ -1013,8 +1033,8 @@
+ +
+#ifdef __linux__ +#ifdef __linux__
+/* +/*
+ * Read and determine active attribute for tty, + * Read and determine active attribute for tty below
+ * the caller has to free the result. + * /sys/class/tty, the caller has to free the result.
+ */ + */
+static +static
+__attribute__((__malloc__)) +__attribute__((__malloc__))
@ -1037,7 +1057,10 @@
+ return ret; + return ret;
+} +}
+ +
+/* Read and determine device attribute for tty */ +/*
+ * Read and determine device attribute for tty below
+ * /sys/class/tty.
+ */
+static +static
+dev_t devattr(const char *tty) +dev_t devattr(const char *tty)
+{ +{
@ -1064,6 +1087,10 @@
+} +}
+#endif /* __linux__ */ +#endif /* __linux__ */
+ +
+/*
+ * Search below /dev for the characer device in
+ * the local `dev_t comparedev' variable.
+ */
static dev_t comparedev; static dev_t comparedev;
-static char* scandev(DIR *dir) -static char* scandev(DIR *dir)
+static +static
@ -1074,11 +1101,14 @@
{ {
char *name = (char*)0; char *name = (char*)0;
struct dirent *dent; struct dirent *dent;
@@ -69,41 +166,310 @@ static char* scandev(DIR *dir) @@ -69,41 +173,335 @@ static char* scandev(DIR *dir)
return name; return name;
} }
-void detect_consoles(void) -void detect_consoles(void)
+/*
+ * Default control characters for an unknown terminal line.
+ */
+static +static
+struct chardata initcp = { +struct chardata initcp = {
+ CERASE, + CERASE,
@ -1087,6 +1117,12 @@
+ 0 + 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 int concount; /* Counter for console IDs */
+ +
+static +static
@ -1117,9 +1153,18 @@
+ consoles->next = tail; + 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__ +#ifdef __linux__
+ char *attrib, *cmdline; + char *attrib, *cmdline;
FILE *fc; FILE *fc;
@ -1127,7 +1172,10 @@
+#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;
@ -1142,6 +1190,9 @@
+ 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.
@ -1186,7 +1237,7 @@
+ closedir(dir); + closedir(dir);
+ if (!consoles) + if (!consoles)
+ goto fallback; + goto fallback;
+ return; + return ret;
+ } + }
+#ifdef __linux__ +#ifdef __linux__
+console: +console:
@ -1220,7 +1271,7 @@
+ } + }
+ 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
@ -1229,7 +1280,7 @@
+ if ((attrib = actattr("console"))) { + if ((attrib = actattr("console"))) {
+ char *words = attrib, *token; + char *words = attrib, *token;
+ DIR *dir; + DIR *dir;
+
+ dir = opendir("/dev"); + dir = opendir("/dev");
+ if (!dir) { + if (!dir) {
+ free(attrib); + free(attrib);
@ -1248,7 +1299,7 @@
+ comparedev = devattr(tmp); + comparedev = devattr(tmp);
+ free(tmp); + free(tmp);
+ } + }
+
+ name = scandev(dir); + name = scandev(dir);
if (!name) if (!name)
continue; continue;
@ -1258,8 +1309,10 @@
+ free(attrib); + free(attrib);
+ if (!consoles) + if (!consoles)
+ goto fallback; + 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 + * Detection of devices used for Linux system console using
@ -1268,7 +1321,9 @@
+ if ((cmdline = oneline("/proc/cmdline"))) { + if ((cmdline = oneline("/proc/cmdline"))) {
+ char *words= cmdline, *token; + char *words= cmdline, *token;
+ DIR *dir; + DIR *dir;
+
- tail->next = (struct console*)0;
- tail->tty = name;
+ dir = opendir("/dev"); + dir = opendir("/dev");
+ if (!dir) { + if (!dir) {
+ free(cmdline); + free(cmdline);
@ -1282,23 +1337,23 @@
+ struct stat st; + struct stat st;
+#endif +#endif
+ char *colon, *name; + char *colon, *name;
+
- if (!consoles)
- consoles = tail;
- else
- consoles->next = tail;
+ if (*token != 'c') + if (*token != 'c')
+ continue; + continue;
+ +
+ if (strncmp(token, "console=", 8) != 0) + if (strncmp(token, "console=", 8) != 0)
+ continue; + continue;
+ token += 8; + token += 8;
+
- if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0)
- perror("memory allocation");
+ if (strcmp(token, "brl") == 0) + if (strcmp(token, "brl") == 0)
+ token += 4; + token += 4;
+ if ((colon = strchr(token, ','))) + if ((colon = strchr(token, ',')))
+ *colon = '\0'; + *colon = '\0';
+
- tail->next = (struct console*)0;
- tail->tty = name;
+ if (asprintf(&name, "/dev/%s", token) < 0) + if (asprintf(&name, "/dev/%s", token) < 0)
+ continue; + continue;
+ +
@ -1328,11 +1383,7 @@
+ } + }
+#endif +#endif
+ close(fd); + close(fd);
+
- if (!consoles)
- consoles = tail;
- else
- consoles->next = tail;
+ name = scandev(dir); + name = scandev(dir);
+ if (!name) + if (!name)
+ continue; + continue;
@ -1376,12 +1427,12 @@
+ 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:
@ -1399,9 +1450,10 @@
+ if (consoles) + if (consoles)
+ consoles->fd = fallback; + consoles->fd = fallback;
} }
+ return ret;
} }
--- src/consoles.h --- 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 @@ @@ -21,13 +21,28 @@
* Author: Werner Fink <werner@suse.de> * Author: Werner Fink <werner@suse.de>
*/ */
@ -1434,7 +1486,7 @@
}; };
extern struct console *consoles; extern struct console *consoles;
-extern void detect_consoles(void); -extern void detect_consoles(void);
+extern void detect_consoles(const char *, int); +extern int detect_consoles(const char *, int);
--- src/Makefile --- src/Makefile
+++ src/Makefile 2010-03-23 15:11:12.000000000 +0000 +++ src/Makefile 2010-03-23 15:11:12.000000000 +0000
@@ -112,7 +112,7 @@ utmpdump: utmpdump.o @@ -112,7 +112,7 @@ utmpdump: utmpdump.o

View File

@ -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 Tue Jun 28 08:36:54 UTC 2011 - aj@suse.de