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 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 <string.h>
#include <sys/types.h>
@ -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 <werner@suse.de>
*/
@ -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

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