passdb-checkpassword.c revision 3ccab0bac68040f179a7de45c516cec258e28fdb
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 2004-2008 Dovecot authors, see the included COPYING file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "common.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "passdb.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#ifdef PASSDB_CHECKPASSWORD
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "db-checkpassword.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct checkpassword_passdb_module {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct passdb_module module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland const char *checkpassword_path, *checkpassword_reply_path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct hash_table *clients;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic struct child_wait *checkpassword_passdb_children = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void checkpassword_request_finish(struct chkpw_auth_request *request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland enum passdb_result result)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct passdb_module *_module = request->request->passdb->passdb;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (struct checkpassword_passdb_module *)_module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland verify_plain_callback_t *callback =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (verify_plain_callback_t *)request->callback;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_remove(module->clients, POINTER_CAST(request->pid));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (result == PASSDB_RESULT_OK) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr(str_c(request->input_buf), '\n') != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request->request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "LF characters in checkpassword reply");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = PASSDB_RESULT_INTERNAL_FAILURE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_set_fields(request->request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland t_strsplit(str_c(request->input_buf), "\t"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland callback(result, request->request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_unref(&request->request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_free(request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcheckpassword_request_half_finish(struct chkpw_auth_request *request)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!request->exited || request->fd_in != -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland switch (request->exit_status) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* vpopmail exit codes: */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 3: /* password fail / vpopmail user not found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 12: /* null user name given */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 13: /* null password given */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 15: /* user has no password */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 20: /* invalid user/domain characters */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 21: /* system user not found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 22: /* system user shadow entry not found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 23: /* system password fail */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* standard checkpassword exit codes: */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 1:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* (1 is additionally defined in vpopmail for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "pop/smtp/webmal/ imap/access denied") */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_info(request->request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "Login failed (status=%d)",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland request->exit_status);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish(request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PASSDB_RESULT_PASSWORD_MISMATCH);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 0:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (request->input_buf != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish(request, PASSDB_RESULT_OK);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* missing input - fall through */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 2:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* checkpassword is called with wrong
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland parameters? unlikely */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 111:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* temporary problem, treat as internal error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland default:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* whatever error.. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request->request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "Child %s exited with status %d",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dec2str(request->pid), request->exit_status);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish(request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PASSDB_RESULT_INTERNAL_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void sigchld_handler(const struct child_wait_status *status,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct chkpw_auth_request *request =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_lookup(module->clients, POINTER_CAST(status->pid));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland switch (checkpassword_sigchld_handler(status, request)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case SIGCHLD_RESULT_UNKNOWN_CHILD:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case SIGCHLD_RESULT_DEAD_CHILD:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case SIGCHLD_RESULT_UNKNOWN_ERROR:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish(request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PASSDB_RESULT_INTERNAL_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case SIGCHLD_RESULT_OK:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_half_finish(request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland request = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void ATTR_NORETURN
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcheckpassword_verify_plain_child(struct auth_request *request,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int fd_in, int fd_out)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland const char *cmd, *const *args;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dup2(fd_out, 3) < 0 || dup2(fd_in, 4) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "dup2() failed: %m");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_setup_env(request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* very simple argument splitting. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cmd = t_strconcat(module->checkpassword_path, " ",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland module->checkpassword_reply_path, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_debug(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "execute: %s", cmd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland args = t_strsplit(cmd, " ");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland execv(args[0], (char **)args);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "execv(%s) failed: %m", args[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland exit(2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcheckpassword_verify_plain(struct auth_request *request, const char *password,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland verify_plain_callback_t *callback)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct passdb_module *_module = request->passdb->passdb;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (struct checkpassword_passdb_module *)_module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct chkpw_auth_request *chkpw_auth_request;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int fd_in[2], fd_out[2];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pid_t pid;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd_in[0] = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pipe(fd_in) < 0 || pipe(fd_out) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "pipe() failed: %m");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fd_in[0] != -1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_in[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_in[1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pid = fork();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pid == -1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "fork() failed: %m");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_in[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_in[1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_out[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_out[1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pid == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_in[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void)close(fd_out[1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_verify_plain_child(request, module,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd_in[1], fd_out[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* not reached */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (close(fd_in[1]) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "close(fd_in[1]) failed: %m");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (close(fd_out[0]) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_log_error(request, "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "close(fd_out[0]) failed: %m");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland auth_request_ref(request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request = i_new(struct chkpw_auth_request, 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->fd_in = fd_in[0];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->fd_out = fd_out[1];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->pid = pid;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->password = i_strdup(password);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->request = request;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->callback = callback;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->half_finish_callback =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_half_finish;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->finish_callback =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->internal_failure_code =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PASSDB_RESULT_INTERNAL_FAILURE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->io_in =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland io_add(fd_in[0], IO_READ, checkpassword_child_input,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request->io_out =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland io_add(fd_out[1], IO_WRITE, checkpassword_child_output,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_insert(module->clients, POINTER_CAST(pid),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkpw_auth_request);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (checkpassword_passdb_children != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland child_wait_add_pid(checkpassword_passdb_children, pid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_passdb_children =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland child_wait_new_with_pid(pid, sigchld_handler, module);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic struct passdb_module *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcheckpassword_preinit(struct auth_passdb *auth_passdb, const char *args)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland module = p_new(auth_passdb->auth->pool,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module, 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland module->checkpassword_path = p_strdup(auth_passdb->auth->pool, args);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland module->checkpassword_reply_path =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKG_LIBEXECDIR"/checkpassword-reply";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland module->clients =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_create(default_pool, default_pool, 0, NULL, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return &module->module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void checkpassword_deinit(struct passdb_module *_module)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct checkpassword_passdb_module *module =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (struct checkpassword_passdb_module *)_module;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct hash_iterate_context *iter;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland void *key, *value;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland iter = hash_table_iterate_init(module->clients);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (hash_table_iterate(iter, &key, &value)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_request_finish(value,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PASSDB_RESULT_INTERNAL_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_iterate_deinit(&iter);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland hash_table_destroy(&module->clients);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (checkpassword_passdb_children != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland child_wait_free(&checkpassword_passdb_children);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct passdb_module_interface passdb_checkpassword = {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "checkpassword",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_preinit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_deinit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland checkpassword_verify_plain,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct passdb_module_interface passdb_checkpassword = {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland MEMBER(name) "checkpassword"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland