diff --git a/systemd-mini.changes b/systemd-mini.changes index dc3e4eb9..fcf4a2ad 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de + +- Fix patch tty-ask-password-agent-on-console.patch not to crash + away but enable it to ask on all devices of /dev/console + ------------------------------------------------------------------- Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de diff --git a/systemd.changes b/systemd.changes index dc3e4eb9..fcf4a2ad 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de + +- Fix patch tty-ask-password-agent-on-console.patch not to crash + away but enable it to ask on all devices of /dev/console + ------------------------------------------------------------------- Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de diff --git a/tty-ask-password-agent-on-console.patch b/tty-ask-password-agent-on-console.patch index e38d027a..ae962403 100644 --- a/tty-ask-password-agent-on-console.patch +++ b/tty-ask-password-agent-on-console.patch @@ -1,11 +1,22 @@ ---- - src/tty-ask-password-agent/tty-ask-password-agent.c | 171 +++++++++++++++++++- - 1 file changed, 166 insertions(+), 5 deletions(-) +From 633a5904c1c4e363a7147f47e2d9fdb1925f7b9f Mon Sep 17 00:00:00 2001 +From: Werner Fink +Date: Fri, 25 Sep 2015 14:28:58 +0200 +Subject: [PATCH] Ask for passphrases not only on the first console of + /dev/console -Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c -=================================================================== ---- systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c -+++ systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c +but also on all other consoles. This does help on e.g. mainframes +where often a serial console together with other consoles are +used. Even rack based servers attachted to both a serial console +as well as having a virtual console do sometimes miss a connected +monitor. +--- + src/tty-ask-password-agent/tty-ask-password-agent.c | 191 ++++++++++++++++++++- + 1 file changed, 186 insertions(+), 5 deletions(-) + +diff --git src/tty-ask-password-agent/tty-ask-password-agent.c src/tty-ask-password-agent/tty-ask-password-agent.c +index 82cbf95..928a5e8 100644 +--- a/src/tty-ask-password-agent/tty-ask-password-agent.c ++++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -31,6 +31,10 @@ #include #include @@ -26,14 +37,13 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c static enum { ACTION_LIST, -@@ -53,6 +59,20 @@ static enum { +@@ -53,6 +59,19 @@ static enum { ACTION_WALL } arg_action = ACTION_QUERY; +struct console { -+ char *tty; + pid_t pid; -+ int id; ++ char *tty; +}; + +static volatile unsigned long *usemask; @@ -47,18 +57,29 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c static bool arg_plymouth = false; static bool arg_console = false; -@@ -211,6 +231,60 @@ static int ask_password_plymouth( +@@ -210,6 +229,69 @@ static int ask_password_plymouth( return 0; } ++static void free_consoles(struct console *con, const unsigned int num) { ++ unsigned int n; ++ if (!con || !num) ++ return; ++ for (n = 0; n < num; n++) ++ free(con[n].tty); ++ free(con); ++} ++ +static const char *current_dev = "/dev/console"; -+static struct console* collect_consoles(int * num) { ++static struct console* collect_consoles(unsigned int * num) { + _cleanup_free_ char *active = NULL; + const char *word, *state; + struct console *con = NULL; -+ size_t con_len; -+ size_t len; -+ int ret, id = 0; ++ size_t con_len = 0, len; ++ int ret; ++ ++ assert(num); ++ assert(*num == 0); + + ret = read_one_line_file("/sys/class/tty/console/active", &active); + if (ret < 0) @@ -71,44 +92,42 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + word = tty; + len = strlen(tty); + } -+ con = greedy_realloc((void**)&con, &con_len, ++id, sizeof(struct console) + 5 + len + 1); ++ con = greedy_realloc((void**)&con, &con_len, 1+(*num), sizeof(struct console)); + if (con == NULL) { + log_oom(); -+ return con; ++ return NULL; + } -+ con->tty = ((char*)con)+sizeof(struct console); -+ sprintf(con->tty, "/dev/%.*s", (int)len, word); -+ con->id = id; ++ if (asprintf(&con[*num].tty, "/dev/%.*s", (int)len, word) < 0) { ++ free_consoles(con, *num); ++ log_oom(); ++ *num = 0; ++ return NULL; ++ } ++ con[*num].pid = 0; ++ (*num)++; + } + if (con == NULL) { + con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console)); + if (con == NULL) { + log_oom(); -+ return con; ++ return NULL; + } -+ con->tty = (char*)current_dev; -+ con->id = id = 1; ++ con[0].tty = strdup(current_dev); ++ if (con[0].tty == NULL) { ++ free_consoles(con, 1); ++ log_oom(); ++ return NULL; ++ } ++ con[0].pid = 0; ++ (*num)++; + } -+ -+ if (num) -+ *num = id; + return con; +} -+ -+static void free_consoles(struct console *con, int num) { -+ int n; -+ -+ if (!con) -+ return; -+ for (n = 0; n < num; n++) -+ free(&con[n]); -+ free(con); -+} + static int parse_password(const char *filename, char **wall) { _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL; uint64_t not_after = 0; -@@ -311,7 +385,7 @@ static int parse_password(const char *filename, char **wall) { +@@ -310,7 +392,7 @@ static int parse_password(const char *filename, char **wall) { _cleanup_free_ char *password = NULL; if (arg_console) { @@ -117,11 +136,20 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c if (tty_fd < 0) return tty_fd; } -@@ -615,8 +689,87 @@ static int parse_argv(int argc, char *argv[]) { +@@ -614,8 +696,90 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -+static int wait_for_answer(void) ++static unsigned int wfa_child(const struct console * con, const unsigned int id) ++{ ++ setsid(); ++ release_terminal(); ++ *usemask |= 1 << id; /* shared memory area */ ++ current_dev = con[id].tty; ++ return id; ++} ++ ++static unsigned int wait_for_answer(void) +{ + struct console *consoles; + struct sigaction sig = { @@ -130,7 +158,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + }; + struct sigaction oldsig; + sigset_t set, oldset; -+ int status = 0, num = 0, n, ret; ++ unsigned int num = 0, id; ++ int status = 0, ret; + pid_t job; + + consoles = collect_consoles(&num); @@ -138,10 +167,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + log_error("Failed to query password: %m"); + exit(EXIT_FAILURE); + } -+ if (num == 1) { -+ n = 1; -+ goto nofork; -+ } ++ if (num < 2) ++ return wfa_child(consoles, 0); + + assert_se(sigemptyset(&set) == 0); + assert_se(sigaddset(&set, SIGHUP) == 0); @@ -152,26 +179,21 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + sig.sa_handler = SIG_DFL; + assert_se(sigaction(SIGHUP, &sig, NULL) == 0); + -+ for (n = 0; n < num; n++) { -+ consoles[n].pid = fork(); ++ for (id = 0; id < num; id++) { ++ consoles[id].pid = fork(); + -+ if (consoles[n].pid < 0) { ++ if (consoles[id].pid < 0) { + log_error("Failed to query password: %m"); + exit(EXIT_FAILURE); + } + -+ if (consoles[n].pid == 0) { ++ if (consoles[id].pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0) + _exit(EXIT_FAILURE); + zero(sig); + assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) == 0); + assert_se(sigaction(SIGCHLD, &oldsig, NULL) == 0); -+ nofork: -+ setsid(); -+ release_terminal(); -+ *usemask |= 1 << consoles[n].id; -+ current_dev = consoles[n].tty; -+ return consoles[n].id; /* child */ ++ return wfa_child(consoles, id); + } + } + @@ -182,16 +204,16 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + break; + continue; + } -+ for (n = 0; n < num; n++) { -+ if (consoles[n].pid == job || kill(consoles[n].pid, 0) < 0) { -+ *usemask &= ~(1 << consoles[n].id); ++ for (id = 0; id < num; id++) { ++ if (consoles[id].pid == job || kill(consoles[id].pid, 0) < 0) { ++ *usemask &= ~(1 << id); /* shared memory area */ + continue; + } -+ if (*usemask & (1 << consoles[n].id)) ++ if (*usemask & (1 << id)) /* shared memory area */ + continue; -+ kill(consoles[n].pid, SIGHUP); ++ kill(consoles[id].pid, SIGHUP); + usleep(50000); -+ kill(consoles[n].pid, SIGKILL); ++ kill(consoles[id].pid, SIGKILL); + } + if (WIFEXITED(status) && ret == 0) + ret = WEXITSTATUS(status); @@ -206,7 +228,7 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c log_set_target(LOG_TARGET_AUTO); log_parse_environment(); -@@ -628,11 +781,27 @@ int main(int argc, char *argv[]) { +@@ -627,11 +791,27 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; @@ -225,8 +247,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c if (arg_console) { - setsid(); - release_terminal(); -+ if (!arg_plymouth && arg_action != ACTION_WALL && -+ arg_action != ACTION_LIST) { ++ if (!arg_plymouth && ++ !IN_SET(arg_action, ACTION_WALL, ACTION_LIST)) { + id = wait_for_answer(); + } else { + setsid(); @@ -237,11 +259,14 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL)) r = watch_passwords(); else -@@ -641,6 +810,7 @@ int main(int argc, char *argv[]) { +@@ -640,6 +820,7 @@ int main(int argc, char *argv[]) { if (r < 0) log_error_errno(r, "Error: %m"); -+ *usemask &= ~(1 << id); ++ *usemask &= ~(1 << id); /* shared memory area */ finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } +-- +2.2.0 +