diff options
| -rw-r--r-- | src/cerberus.c | 49 | ||||
| -rw-r--r-- | 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"); @@ -139,6 +135,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 * * @param argc The number of command line arguments @@ -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); |
