From 3b0aa46ba276e5a3559ec2859a16b579f3d15273 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 29 Oct 2014 21:54:55 +0100 Subject: fixs stdin problems on successful login, we needed to wait for the child, but I do not understand why, although we shoul have done that anyway, I just forgot it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/cerberus.c | 49 +++++++++++++++++++++++++++++++++++++------------ src/cerberus.h | 1 + 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/cerberus.c b/src/cerberus.c index 1479771..7195f80 100644 --- a/src/cerberus.c +++ b/src/cerberus.c @@ -71,11 +71,7 @@ int main(int argc, char** argv) signal(SIGINT, SIG_IGN); /* Run login hook */ - if (fork() == 0) - { - exec_hook(HOOK_LOGIN, argc, argv); - return 0; - } + fork_exec_wait_hook(HOOK_LOGIN, argc, argv); /* Wait for the login shell and all grandchildren to exit */ while ((wait(NULL) == -1) && (errno == EINTR)) @@ -118,10 +114,10 @@ void exec_hook(int hook, int argc, char** argv) [HOOK_LOGOUT] = "logout", [HOOK_DENIED] = "denied", }; - - char** args = malloc((size_t)(argc + 2) * sizeof(char*)); + char** args; int i; + args = malloc((size_t)(argc + 2) * sizeof(char*)); if (args == NULL) { perror("malloc"); @@ -138,6 +134,39 @@ void exec_hook(int hook, int argc, char** argv) } +/** + * Fork-exec-wait /etc/cerberusrc + * + * @param hook The ID of the hook to run + * @param argc The number of command line arguments + * @param argv The command line arguments + */ +void fork_exec_wait_hook(int hook, int argc, char** argv) +{ + pid_t pid, reaped; + pid = fork(); + if (pid == -1) + return; + if (pid == 0) + { + close(STDIN_FILENO); + exec_hook(hook, argc, argv); + _exit(1); + } + for (;;) + { + reaped = wait(NULL); + if (reaped == -1) + { + perror("wait"); + return; + } + if (reaped == pid) + return; + } +} + + /** * Do everything before the fork and do everything the exec fork * @@ -303,11 +332,7 @@ void do_login(int argc, char** argv) printf("(auto-authenticated)\n"); if (ret == 0) { - if (fork() == 0) - { - exec_hook(HOOK_DENIED, argc, argv); - _exit(0); - } + fork_exec_wait_hook(HOOK_DENIED, argc, argv); sleep(FAILURE_SLEEP); _exit(1); } diff --git a/src/cerberus.h b/src/cerberus.h index 96c89ab..9960fa7 100644 --- a/src/cerberus.h +++ b/src/cerberus.h @@ -51,6 +51,7 @@ #endif +void fork_exec_wait_hook(int hook, int argc, char** argv); void exec_hook(int hook, int argc, char** argv); void do_login(int argc, char** argv); -- cgit v1.2.3-70-g09d2