From b695b9b51ec0559b7023855f1f87e0ef04723e66 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Tue, 15 Dec 2015 23:25:42 +0100 Subject: do not always rethrow authentication error the status is rethrown only in case of PAM_SUCCESS or PAM_AUTH_ERR. Signed-off-by: Olivier Gayot --- multi_auth.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/multi_auth.c b/multi_auth.c index 9140036..270e773 100644 --- a/multi_auth.c +++ b/multi_auth.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -27,6 +28,7 @@ struct auth_module_t { void *dl_handler; pid_t pid; + bool active; }; static @@ -95,6 +97,7 @@ static int perform_auth(void) int clone_flags = CLONE_NEWUTS|SIGCHLD; modules_g[i].pid = clone(module_auth_main, stack + STACK_SIZE, clone_flags, &mod->args); + modules_g[i].active = true; if (modules_g[i].pid == -1) { return PAM_SYSTEM_ERR; @@ -103,19 +106,40 @@ static int perform_auth(void) } siginfo_t infos; + int modules_terminated = 0; + int ret = PAM_AUTH_ERR; - /* wait for a first child to exit or be killed */ - waitid(P_ALL, 0, &infos, WEXITED); + do { + /* wait for a first child to exit or be killed */ + waitid(P_ALL, 0, &infos, WEXITED); - int ret = infos.si_status; + ++modules_terminated; + + /* find the process matching the pid */ + for (int i = 0; i < countof(modules_g); ++i) { + struct auth_module_t *mod = &modules_g[i]; + + if (mod->pid == infos.si_pid) { + mod->active = false; + break; + } + } + + if (infos.si_status == PAM_SUCCESS || infos.si_status == PAM_AUTH_ERR) { + ret = infos.si_status; + break; + } + + } while (modules_terminated < countof(modules_g)); for (int i = 0; i < countof(modules_g); ++i) { - if (modules_g[i].pid == infos.si_pid) { + struct auth_module_t *mod = &modules_g[i]; + + if (!mod->active) continue; - } - kill(modules_g[i].pid, SIGKILL); - waitpid(modules_g[i].pid, NULL, 0); + kill(mod->pid, SIGKILL); + waitpid(mod->pid, NULL, 0); } return ret; -- cgit v1.2.3