]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Remove checkpassword driver
authorAki Tuomi <aki.tuomi@open-xchange.com>
Sun, 27 Mar 2022 17:21:33 +0000 (20:21 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 31 Mar 2022 07:55:29 +0000 (07:55 +0000)
15 files changed:
.gitignore
configure.ac
doc/example-config/conf.d/10-auth.conf
doc/example-config/conf.d/Makefile.am
doc/example-config/conf.d/auth-checkpassword.conf.ext [deleted file]
m4/want_checkpassword.m4 [deleted file]
src/auth/Makefile.am
src/auth/checkpassword-reply.c [deleted file]
src/auth/db-checkpassword.c [deleted file]
src/auth/db-checkpassword.h [deleted file]
src/auth/passdb-checkpassword.c [deleted file]
src/auth/passdb.c
src/auth/userdb-checkpassword.c [deleted file]
src/auth/userdb.c
src/master/main.c

index 8bd3b1e445c615cba96ab3920a35241f2a203577..331354aec8a6868fd65488a041cd3069ed03670f 100644 (file)
@@ -110,7 +110,6 @@ doc/example-config/README
 doc/wiki/*.txt
 doc/wiki/Makefile.am
 src/anvil/anvil
-src/auth/checkpassword-reply
 src/auth/auth
 src/config/all-settings.c
 src/config/config
index 11c2c567038d70cc3babba53d986efe323296921..f537b695d085d643e1916b855343e54cd238ce18 100644 (file)
@@ -256,7 +256,6 @@ AM_CONDITIONAL(BUILD_DOCS, test "$want_docs" = "yes")
 dnl always enable all of the passbs and userdbs that don't require extra libs
 want_passwd=yes
 want_passwd_file=yes
-want_checkpassword=yes
 want_prefetch_userdb=yes
 
 AC_ISC_POSIX
@@ -537,7 +536,6 @@ DOVECOT_WANT_LUA
 DOVECOT_WANT_PREFETCH
 DOVECOT_WANT_PASSWD
 DOVECOT_WANT_PAM
-DOVECOT_WANT_CHECKPASSWORD
 DOVECOT_WANT_BSDAUTH
 DOVECOT_WANT_GSSAPI
 DOVECOT_WANT_LDAP
index af58f64bd289a6234a3820513425d84ff041e7ec..555306aa9917b86acf5bf7e97b76fe9ffa88d250 100644 (file)
@@ -118,5 +118,4 @@ auth_mechanisms = plain
 #!include auth-sql.conf.ext
 #!include auth-ldap.conf.ext
 #!include auth-passwdfile.conf.ext
-#!include auth-checkpassword.conf.ext
 #!include auth-static.conf.ext
index 1950fd518b7844ca44f7136131bed8184ec40cc6..9f4797e5e68ed93e944eada44d413d063272041d 100644 (file)
@@ -2,7 +2,6 @@ pkgsysconfdir = $(sysconfdir)/dovecot
 
 exampledir = $(docdir)/example-config/conf.d
 example_DATA = \
-       auth-checkpassword.conf.ext \
        auth-deny.conf.ext \
        auth-dict.conf.ext \
        auth-ldap.conf.ext \
diff --git a/doc/example-config/conf.d/auth-checkpassword.conf.ext b/doc/example-config/conf.d/auth-checkpassword.conf.ext
deleted file mode 100644 (file)
index b2fb13a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Authentication for checkpassword users. Included from 10-auth.conf.
-#
-# <doc/wiki/AuthDatabase.CheckPassword.txt>
-
-passdb {
-  driver = checkpassword
-  args = /usr/bin/checkpassword
-}
-
-# passdb lookup should return also userdb info
-userdb {
-  driver = prefetch
-}
-
-# Standard checkpassword doesn't support direct userdb lookups.
-# If you need checkpassword userdb, the checkpassword must support
-# Dovecot-specific extensions.
-#userdb {
-#  driver = checkpassword
-#  args = /usr/bin/checkpassword
-#}
diff --git a/m4/want_checkpassword.m4 b/m4/want_checkpassword.m4
deleted file mode 100644 (file)
index 696adb4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-AC_DEFUN([DOVECOT_WANT_CHECKPASSWORD], [
-  if test $want_checkpassword != no; then
-          AC_DEFINE(PASSDB_CHECKPASSWORD,, [Build with checkpassword passdb support])
-          AC_DEFINE(USERDB_CHECKPASSWORD,, [Build with checkpassword userdb support])
-          passdb="$passdb checkpassword"
-          userdb="$userdb checkpassword"
-  else
-          not_passdb="$not_passdb checkpassword"
-          not_userdb="$not_userdb checkpassword"
-  fi
-])
index c7c34719bdd55a0b9c22d74f5d1bfbadd4c139ef..2ec06b4414a126a0066cab31201b0e2f740b408a 100644 (file)
@@ -33,7 +33,7 @@ auth_module_LTLIBRARIES = \
 
 pkglibexecdir = $(libexecdir)/dovecot
 
-pkglibexec_PROGRAMS = auth checkpassword-reply
+pkglibexec_PROGRAMS = auth
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
@@ -105,7 +105,6 @@ libauth_la_SOURCES = \
        auth-token.c \
        auth-worker-connection.c \
        auth-worker-server.c \
-       db-checkpassword.c \
        db-dict.c \
        db-dict-cache-key.c \
        db-oauth2.c \
@@ -129,7 +128,6 @@ libauth_la_SOURCES = \
        passdb-blocking.c \
        passdb-bsdauth.c \
        passdb-cache.c \
-       passdb-checkpassword.c \
        passdb-dict.c \
        passdb-oauth2.c \
        passdb-passwd.c \
@@ -140,7 +138,6 @@ libauth_la_SOURCES = \
        passdb-template.c \
        userdb.c \
        userdb-blocking.c \
-       userdb-checkpassword.c \
        userdb-dict.c \
        userdb-passwd.c \
        userdb-passwd-file.c \
@@ -176,7 +173,6 @@ headers = \
        db-ldap.h \
        db-sql.h \
        db-passwd-file.h \
-       db-checkpassword.h \
        db-oauth2.h \
        mech.h \
        mycrypt.h \
@@ -223,13 +219,6 @@ libauthdb_imap_la_SOURCES = passdb-imap.c
 pkginc_libdir=$(pkgincludedir)
 pkginc_lib_HEADERS = $(headers)
 
-checkpassword_reply_CPPFLAGS = $(AM_CPPFLAGS) $(BINARY_CFLAGS)
-checkpassword_reply_LDADD = $(LIBDOVECOT) $(BINARY_LDFLAGS)
-checkpassword_reply_DEPENDENCIES = $(LIBDOVECOT_DEPS)
-
-checkpassword_reply_sources = \
-       checkpassword-reply.c
-
 test_programs = \
        test-libpassword \
        test-auth-cache \
diff --git a/src/auth/checkpassword-reply.c b/src/auth/checkpassword-reply.c
deleted file mode 100644 (file)
index 71f231a..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* simple checkpassword wrapper to send userdb data back to dovecot-auth */
-
-#include "lib.h"
-#include "str.h"
-#include "strescape.h"
-#include "write-full.h"
-
-#include <unistd.h>
-
-int main(void)
-{
-       string_t *str;
-       const char *user, *home, *authorized, *orig_uid_env;
-       const char *extra_env, *key, *value, *const *tmp;
-       bool uid_found = FALSE, gid_found = FALSE;
-       uid_t orig_uid;
-
-       lib_init();
-       str = t_str_new(1024);
-
-       orig_uid_env = getenv("ORIG_UID");
-       if (orig_uid_env == NULL || str_to_uid(orig_uid_env, &orig_uid) < 0)
-               orig_uid = (uid_t)-1;
-
-       /* ORIG_UID should have the auth process's UID that forked us.
-          if the checkpassword changed the UID, this could be a security hole
-          because the UID's other processes can ptrace this process and write
-          any kind of a reply to fd 4. so we can run only if:
-
-          a) INSECURE_SETUID environment is set.
-          b) process isn't ptraceable (this binary is setuid/setgid)
-          c) checkpassword didn't actually change the UID (but used
-             userdb_uid instead)
-          */
-       if (getenv("INSECURE_SETUID") == NULL &&
-           (orig_uid == (uid_t)-1 || orig_uid != getuid()) &&
-           getuid() == geteuid() && getgid() == getegid()) {
-               if (orig_uid_env == NULL) {
-                       i_error("checkpassword: ORIG_UID environment was dropped by checkpassword. "
-                               "Can't verify if we're safe to run. See "
-                               "http://wiki2.dovecot.org/AuthDatabase/CheckPassword#Security");
-               } else {
-                       i_error("checkpassword: The checkpassword couldn't be run securely. See "
-                               "http://wiki2.dovecot.org/AuthDatabase/CheckPassword#Security");
-               }
-               return 111;
-       }
-
-       user = getenv("USER");
-       if (user != NULL) {
-               if (strchr(user, '\t') != NULL) {
-                       i_error("checkpassword: USER contains TAB");
-                       return 1;
-               }
-               str_printfa(str, "user=");
-               str_append_tabescaped(str, user);
-               str_append_c(str, '\t');
-       }
-
-       home = getenv("HOME");
-       if (home != NULL) {
-               if (strchr(home, '\t') != NULL) {
-                       i_error("checkpassword: HOME contains TAB");
-                       return 1;
-               }
-               str_printfa(str, "userdb_home=");
-               str_append_tabescaped(str, home);
-               str_append_c(str, '\t');
-       }
-
-       extra_env = getenv("EXTRA");
-       if (extra_env != NULL) {
-               for (tmp = t_strsplit(extra_env, " "); *tmp != NULL; tmp++) {
-                       value = getenv(*tmp);
-                       if (value != NULL) {
-                               key = t_str_lcase(*tmp);
-                               if (strcmp(key, "userdb_uid") == 0)
-                                       uid_found = TRUE;
-                               else if (strcmp(key, "userdb_gid") == 0)
-                                       gid_found = TRUE;
-                               str_append_tabescaped(str, key);
-                               str_append_c(str, '=');
-                               str_append_tabescaped(str, value);
-                               str_append_c(str, '\t');
-                       }
-               }
-       }
-       if (!uid_found)
-               str_printfa(str, "userdb_uid=%s\t",  dec2str(getuid()));
-       if (!gid_found)
-               str_printfa(str, "userdb_gid=%s\t",  dec2str(getgid()));
-
-       i_assert(str_len(str) > 0);
-
-       if (write_full(4, str_data(str), str_len(str)) < 0) {
-               i_error("checkpassword: write_full() failed: %m");
-               lib_exit(111);
-       }
-       authorized = getenv("AUTHORIZED");
-       if (authorized == NULL) {
-               /* authentication */
-               return 0;
-       } else if (strcmp(authorized, "2") == 0) {
-               /* successful passdb/userdb lookup */
-               return 2;
-       } else {
-               i_error("checkpassword: Script doesn't support passdb/userdb lookup");
-               return 111;
-       }
-}
diff --git a/src/auth/db-checkpassword.c b/src/auth/db-checkpassword.c
deleted file mode 100644 (file)
index 7d52eef..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
-
-#include "auth-common.h"
-
-#if defined(PASSDB_CHECKPASSWORD) || defined(USERDB_CHECKPASSWORD)
-
-#include "lib-signals.h"
-#include "array.h"
-#include "buffer.h"
-#include "str.h"
-#include "ioloop.h"
-#include "hash.h"
-#include "execv-const.h"
-#include "env-util.h"
-#include "safe-memset.h"
-#include "strescape.h"
-#include "child-wait.h"
-#include "db-checkpassword.h"
-
-#include <unistd.h>
-#include <sys/wait.h>
-
-#define CHECKPASSWORD_MAX_REQUEST_LEN 512
-
-struct chkpw_auth_request {
-       struct db_checkpassword *db;
-       struct auth_request *request;
-       char *auth_password;
-
-       db_checkpassword_callback_t *callback;
-       void (*request_callback)();
-
-       pid_t pid;
-       int fd_out, fd_in;
-       struct io *io_out, *io_in;
-
-       string_t *input_buf;
-       size_t output_pos, output_len;
-
-       int exit_status;
-       bool exited:1;
-};
-
-struct db_checkpassword {
-       char *checkpassword_path, *checkpassword_reply_path;
-
-       HASH_TABLE(void *, struct chkpw_auth_request *) clients;
-       struct child_wait *child_wait;
-};
-
-static void
-env_put_extra_fields(const ARRAY_TYPE(auth_field) *extra_fields)
-{
-       const struct auth_field *field;
-       const char *key, *value;
-
-       array_foreach(extra_fields, field) {
-               key = t_str_ucase(field->key);
-               value = field->value != NULL ? field->value : "1";
-               env_put(key, value);
-       }
-}
-
-static void checkpassword_request_close(struct chkpw_auth_request *request)
-{
-       io_remove(&request->io_in);
-       io_remove(&request->io_out);
-
-       i_close_fd(&request->fd_in);
-       i_close_fd(&request->fd_out);
-}
-
-static void checkpassword_request_free(struct chkpw_auth_request **_request)
-{
-       struct chkpw_auth_request *request = *_request;
-
-       *_request = NULL;
-
-       if (!request->exited) {
-               hash_table_remove(request->db->clients,
-                                 POINTER_CAST(request->pid));
-               child_wait_remove_pid(request->db->child_wait, request->pid);
-       }
-       checkpassword_request_close(request);
-
-       if (request->auth_password != NULL) {
-               safe_memset(request->auth_password, 0,
-                           strlen(request->auth_password));
-               i_free(request->auth_password);
-       }
-       auth_request_unref(&request->request);
-       str_free(&request->input_buf);
-       i_free(request);
-}
-
-static void checkpassword_finish(struct chkpw_auth_request **_request,
-                                enum db_checkpassword_status status)
-{
-       struct chkpw_auth_request *request = *_request;
-       const char *const *extra_fields;
-
-       *_request = NULL;
-
-       extra_fields = t_strsplit_tabescaped(str_c(request->input_buf));
-       request->callback(request->request, status, extra_fields,
-                         request->request_callback);
-       checkpassword_request_free(&request);
-}
-
-static void checkpassword_internal_failure(struct chkpw_auth_request **request)
-{
-       checkpassword_finish(request, DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE);
-}
-
-static void
-checkpassword_request_finish_auth(struct chkpw_auth_request *request)
-{
-       switch (request->exit_status) {
-       /* standard checkpassword exit codes: */
-       case 1:
-               e_info(authdb_event(request->request),
-                      "Login failed (status=%d)",
-                      request->exit_status);
-               checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_FAILURE);
-               break;
-       case 0:
-               if (request->input_buf->used == 0) {
-                       e_error(authdb_event(request->request),
-                               "Received no input");
-                       checkpassword_internal_failure(&request);
-                       break;
-               }
-               checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_OK);
-               break;
-       case 2:
-               /* checkpassword is called with wrong parameters? unlikely */
-               e_error(authdb_event(request->request),
-                       "Child %s exited with status 2 (tried to use "
-                       "userdb-only checkpassword program for passdb?)",
-                       dec2str(request->pid));
-               checkpassword_internal_failure(&request);
-               break;
-       case 111:
-               /* temporary problem, treat as internal error */
-       default:
-               /* whatever error.. */
-               e_error(authdb_event(request->request),
-                       "Child %s exited with status %d",
-                       dec2str(request->pid), request->exit_status);
-               checkpassword_internal_failure(&request);
-               break;
-       }
-}
-
-static void
-checkpassword_request_finish_lookup(struct chkpw_auth_request *request)
-{
-       switch (request->exit_status) {
-       case 3:
-               /* User does not exist. */
-               e_info(authdb_event(request->request),
-                      "User unknown");
-               checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_FAILURE);
-               break;
-       case 2:
-               /* This is intentionally not 0. checkpassword-reply exits with
-                  2 on success when AUTHORIZED is set. */
-               if (request->input_buf->used == 0) {
-                       e_error(authdb_event(request->request),
-                               "Received no input");
-                       checkpassword_internal_failure(&request);
-                       break;
-               }
-               checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_OK);
-               break;
-       default:
-               /* whatever error... */
-               e_error(authdb_event(request->request),
-                       "Child %s exited with status %d",
-                       dec2str(request->pid), request->exit_status);
-               checkpassword_internal_failure(&request);
-               break;
-       }
-}
-
-static void
-checkpassword_request_half_finish(struct chkpw_auth_request *request)
-{
-       /* the process must have exited, and the input fd must have closed */
-       if (!request->exited || request->fd_in != -1)
-               return;
-
-       if (request->auth_password != NULL)
-               checkpassword_request_finish_auth(request);
-       else
-               checkpassword_request_finish_lookup(request);
-}
-
-static void env_put_auth_vars(struct auth_request *request)
-{
-       const struct var_expand_table *tab;
-       unsigned int i;
-
-       tab = auth_request_get_var_expand_table(request, NULL);
-       for (i = 0; tab[i].key != '\0' || tab[i].long_key != NULL; i++) {
-               /* avoid keeping passwords in environment .. just in case
-                  an attacker might find it from there. environment is no
-                  longer world-readable in modern OSes, but maybe the attacker
-                  could be running with the same UID. of course then the
-                  attacker could usually ptrace() the process, except that is
-                  disabled on some secured systems. so, although I find it
-                  highly unlikely anyone could actually attack Dovecot this
-                  way in a real system, be safe just in case. besides, lets
-                  try to keep at least minimally compatible with the
-                  checkpassword API. */
-               if (tab[i].long_key != NULL && tab[i].value != NULL &&
-                   strcasecmp(tab[i].long_key, "password") != 0) {
-                       env_put(t_strdup_printf("AUTH_%s",
-                                               t_str_ucase(tab[i].long_key)),
-                               tab[i].value);
-               }
-       }
-}
-
-static void checkpassword_setup_env(struct auth_request *request)
-{
-       const struct auth_request_fields *fields = &request->fields;
-
-       /* Besides passing the standard username and password in a
-          pipe, also pass some other possibly interesting information
-          via environment. Use UCSPI names for local/remote IPs. */
-       env_put("PROTO", "TCP"); /* UCSPI */
-       env_put("ORIG_UID", dec2str(getuid()));
-       env_put("SERVICE", fields->service);
-       if (fields->local_ip.family != 0) {
-               env_put("TCPLOCALIP", net_ip2addr(&fields->local_ip));
-               /* FIXME: for backwards compatibility only,
-                  remove some day */
-               env_put("LOCAL_IP", net_ip2addr(&fields->local_ip));
-       }
-       if (fields->remote_ip.family != 0) {
-               env_put("TCPREMOTEIP", net_ip2addr(&fields->remote_ip));
-               /* FIXME: for backwards compatibility only,
-                  remove some day */
-               env_put("REMOTE_IP", net_ip2addr(&fields->remote_ip));
-       }
-       if (fields->local_port != 0)
-               env_put("TCPLOCALPORT", dec2str(fields->local_port));
-       if (fields->remote_port != 0)
-               env_put("TCPREMOTEPORT", dec2str(fields->remote_port));
-       if (fields->master_user != NULL)
-               env_put("MASTER_USER", fields->master_user);
-       if (!auth_fields_is_empty(fields->extra_fields)) {
-               const ARRAY_TYPE(auth_field) *extra_fields =
-                       auth_fields_export(fields->extra_fields);
-
-               /* extra fields could come from master db */
-               env_put_extra_fields(extra_fields);
-       }
-       env_put_auth_vars(request);
-}
-
-static const char *
-checkpassword_get_cmd(struct auth_request *request, const char *args,
-                     const char *checkpassword_reply_path)
-{
-       string_t *str;
-       const char *error;
-
-       str = t_str_new(256);
-       if (auth_request_var_expand(str, args, request, NULL, &error) <= 0) {
-               e_error(authdb_event(request),
-                       "Failed to expand checkpassword_path=%s: %s",
-                       args, error);
-       }
-
-       return t_strconcat(str_c(str), " ", checkpassword_reply_path, NULL);
-}
-
-static void checkpassword_child_input(struct chkpw_auth_request *request)
-{
-       unsigned char buf[1024];
-       ssize_t ret;
-
-       ret = read(request->fd_in, buf, sizeof(buf));
-       if (ret > 0) {
-               str_append_data(request->input_buf, buf, ret);
-               return;
-       }
-
-       if (ret < 0) {
-               e_error(authdb_event(request->request),
-                       "read() failed: %m");
-               checkpassword_internal_failure(&request);
-       } else if (memchr(str_data(request->input_buf), '\0',
-                         str_len(request->input_buf)) != NULL) {
-               e_error(authdb_event(request->request),
-                       "NUL characters in checkpassword reply");
-               checkpassword_internal_failure(&request);
-       } else if (strchr(str_c(request->input_buf), '\n') != NULL) {
-               e_error(authdb_event(request->request),
-                       "LF characters in checkpassword reply");
-               checkpassword_internal_failure(&request);
-       } else {
-               e_debug(authdb_event(request->request),
-                       "Received input: %s", str_c(request->input_buf));
-               checkpassword_request_close(request);
-               checkpassword_request_half_finish(request);
-       }
-}
-
-static void checkpassword_child_output(struct chkpw_auth_request *request)
-{
-       /* Send: username \0 password \0 timestamp \0.
-          Must be 512 bytes or less. The "timestamp" parameter is actually
-          useful only for APOP authentication. We don't support it, so
-          keep it empty */
-       struct auth_request *auth_request = request->request;
-       buffer_t *buf;
-       const unsigned char *data;
-       size_t size;
-       ssize_t ret;
-
-       buf = t_buffer_create(CHECKPASSWORD_MAX_REQUEST_LEN);
-       buffer_append(buf, auth_request->fields.user,
-                     strlen(auth_request->fields.user)+1);
-       if (request->auth_password != NULL) {
-               buffer_append(buf, request->auth_password,
-                             strlen(request->auth_password)+1);
-       } else {
-               buffer_append_c(buf, '\0');
-       }
-       buffer_append_c(buf, '\0');
-       data = buffer_get_data(buf, &size);
-
-       i_assert(size == request->output_len);
-       /* already checked this */
-       i_assert(size <= CHECKPASSWORD_MAX_REQUEST_LEN);
-
-       ret = write(request->fd_out, data + request->output_pos,
-                   size - request->output_pos);
-       if (ret <= 0) {
-               if (ret < 0) {
-                       e_error(authdb_event(request->request),
-                               "write() failed: %m");
-               } else {
-                       e_error(authdb_event(request->request),
-                               "write() returned 0");
-               }
-               checkpassword_internal_failure(&request);
-               return;
-       }
-
-       request->output_pos += ret;
-       if (request->output_pos < size)
-               return;
-
-       /* finished sending the data */
-       io_remove(&request->io_out);
-
-       if (close(request->fd_out) < 0)
-               e_error(authdb_event(request->request), "close() failed: %m");
-       request->fd_out = -1;
-}
-
-static void ATTR_NORETURN
-checkpassword_exec(struct db_checkpassword *db, struct auth_request *request,
-                  int fd_in, int fd_out, bool authenticate)
-{
-       const char *cmd, *const *args;
-
-       /* fd 3 is used to send the username+password for the script
-          fd 4 is used to communicate with checkpassword-reply */
-       if (dup2(fd_out, 3) < 0 || dup2(fd_in, 4) < 0) {
-               e_error(authdb_event(request),
-                       "dup2() failed: %m");
-               lib_exit(111);
-       }
-
-       if (!authenticate) {
-               /* We want to retrieve passdb/userdb data and don't do
-                  authorization, so we need to signalize the
-                  checkpassword program that the password shall be
-                  ignored by setting AUTHORIZED.  This needs a
-                  special checkpassword program which knows how to
-                  handle this. */
-               env_put("AUTHORIZED", "1");
-               if (request->wanted_credentials_scheme != NULL) {
-                       /* passdb credentials lookup */
-                       env_put("CREDENTIALS_LOOKUP", "1");
-                       env_put("SCHEME", request->wanted_credentials_scheme);
-               }
-       }
-       checkpassword_setup_env(request);
-       cmd = checkpassword_get_cmd(request, db->checkpassword_path,
-                                   db->checkpassword_reply_path);
-       e_debug(authdb_event(request), "execute: %s", cmd);
-
-       /* very simple argument splitting. */
-       args = t_strsplit(cmd, " ");
-       execv_const(args[0], args);
-}
-
-static void sigchld_handler(const struct child_wait_status *status,
-                           struct db_checkpassword *db)
-{
-       struct chkpw_auth_request *request = 
-               hash_table_lookup(db->clients, POINTER_CAST(status->pid));
-
-       i_assert(request != NULL);
-
-       hash_table_remove(db->clients, POINTER_CAST(status->pid));
-       request->exited = TRUE;
-
-       if (WIFSIGNALED(status->status)) {
-               e_error(authdb_event(request->request),
-                       "Child %s died with signal %d",
-                       dec2str(status->pid), WTERMSIG(status->status));
-               checkpassword_internal_failure(&request);
-       } else if (WIFEXITED(status->status)) {
-               request->exit_status = WEXITSTATUS(status->status);
-
-               e_debug(authdb_event(request->request),
-                       "exit_status=%d", request->exit_status);
-               checkpassword_request_half_finish(request);
-       } else {
-               /* shouldn't happen */
-               e_debug(authdb_event(request->request),
-                       "Child %s exited with status=%d",
-                       dec2str(status->pid), status->status);
-               checkpassword_internal_failure(&request);
-       }
-}
-
-void db_checkpassword_call(struct db_checkpassword *db,
-                          struct auth_request *request,
-                          const char *auth_password,
-                          db_checkpassword_callback_t *callback,
-                          void (*request_callback)())
-{
-       struct chkpw_auth_request *chkpw_auth_request;
-       size_t output_len;
-       int fd_in[2], fd_out[2];
-       pid_t pid;
-
-       /* <username> \0 <password> \0 timestamp \0 */
-       output_len = strlen(request->fields.user) + 3;
-       if (auth_password != NULL)
-               output_len += strlen(auth_password);
-       if (output_len > CHECKPASSWORD_MAX_REQUEST_LEN) {
-               e_info(authdb_event(request),
-                      "Username+password combination too long (%zu bytes)",
-                      output_len);
-               callback(request, DB_CHECKPASSWORD_STATUS_FAILURE,
-                        NULL, request_callback);
-               return;
-       }
-
-       fd_in[0] = -1;
-       if (pipe(fd_in) < 0 || pipe(fd_out) < 0) {
-               e_error(authdb_event(request),
-                       "pipe() failed: %m");
-               if (fd_in[0] != -1) {
-                       i_close_fd(&fd_in[0]);
-                       i_close_fd(&fd_in[1]);
-               }
-               callback(request, DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE,
-                        NULL, request_callback);
-               return;
-       }
-
-       pid = fork();
-       if (pid == -1) {
-               e_error(authdb_event(request),
-                       "fork() failed: %m");
-               i_close_fd(&fd_in[0]);
-               i_close_fd(&fd_in[1]);
-               i_close_fd(&fd_out[0]);
-               i_close_fd(&fd_out[1]);
-               callback(request, DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE,
-                        NULL, request_callback);
-               return;
-       }
-
-       if (pid == 0) {
-               /* child */
-               i_close_fd(&fd_in[0]);
-               i_close_fd(&fd_out[1]);
-               checkpassword_exec(db, request, fd_in[1], fd_out[0],
-                                  auth_password != NULL);
-               /* not reached */
-       }
-
-       if (close(fd_in[1]) < 0) {
-               e_error(authdb_event(request),
-                       "close(fd_in[1]) failed: %m");
-       }
-       if (close(fd_out[0]) < 0) {
-               e_error(authdb_event(request),
-                       "close(fd_out[0]) failed: %m");
-       }
-
-       auth_request_ref(request);
-       chkpw_auth_request = i_new(struct chkpw_auth_request, 1);
-       chkpw_auth_request->db = db;
-       chkpw_auth_request->pid = pid;
-       chkpw_auth_request->fd_in = fd_in[0];
-       chkpw_auth_request->fd_out = fd_out[1];
-       chkpw_auth_request->auth_password = i_strdup(auth_password);
-       chkpw_auth_request->request = request;
-       chkpw_auth_request->output_len = output_len;
-       chkpw_auth_request->input_buf = str_new(default_pool, 256);
-       chkpw_auth_request->callback = callback;
-       chkpw_auth_request->request_callback = request_callback;
-
-       chkpw_auth_request->io_in =
-               io_add(fd_in[0], IO_READ, checkpassword_child_input,
-                      chkpw_auth_request);
-       chkpw_auth_request->io_out =
-               io_add(fd_out[1], IO_WRITE, checkpassword_child_output,
-                      chkpw_auth_request);
-
-       hash_table_insert(db->clients, POINTER_CAST(pid), chkpw_auth_request);
-       child_wait_add_pid(db->child_wait, pid);
-}
-
-struct db_checkpassword *
-db_checkpassword_init(const char *checkpassword_path,
-                     const char *checkpassword_reply_path)
-{
-       struct db_checkpassword *db;
-
-       db = i_new(struct db_checkpassword, 1);
-       db->checkpassword_path = i_strdup(checkpassword_path);
-       db->checkpassword_reply_path = i_strdup(checkpassword_reply_path);
-       hash_table_create_direct(&db->clients, default_pool, 0);
-       db->child_wait =
-               child_wait_new_with_pid((pid_t)-1, sigchld_handler, db);
-       return db;
-}
-
-void db_checkpassword_deinit(struct db_checkpassword **_db)
-{
-       struct db_checkpassword *db = *_db;
-       struct hash_iterate_context *iter;
-       void *key;
-       struct chkpw_auth_request *request;
-
-       *_db = NULL;
-
-       iter = hash_table_iterate_init(db->clients);
-       while (hash_table_iterate(iter, db->clients, &key, &request))
-               checkpassword_internal_failure(&request);
-       hash_table_iterate_deinit(&iter);
-
-       child_wait_free(&db->child_wait);
-       hash_table_destroy(&db->clients);
-       i_free(db->checkpassword_reply_path);
-       i_free(db->checkpassword_path);
-       i_free(db);
-}
-
-#endif
diff --git a/src/auth/db-checkpassword.h b/src/auth/db-checkpassword.h
deleted file mode 100644 (file)
index 64eedd8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef CHECKPASSWORD_COMMON_H
-#define CHECKPASSWORD_COMMON_H
-
-#include "auth-request.h"
-
-enum db_checkpassword_status {
-       DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE = -1,
-       /* auth unsuccessful / user not found */
-       DB_CHECKPASSWORD_STATUS_FAILURE = 0,
-       DB_CHECKPASSWORD_STATUS_OK = 1
-};
-
-typedef void db_checkpassword_callback_t(struct auth_request *request,
-                                        enum db_checkpassword_status status,
-                                        const char *const *extra_fields,
-                                        void (*request_callback)());
-
-struct db_checkpassword *
-db_checkpassword_init(const char *checkpassword_path,
-                     const char *checkpassword_reply_path);
-void db_checkpassword_deinit(struct db_checkpassword **db);
-
-void db_checkpassword_call(struct db_checkpassword *db,
-                          struct auth_request *request,
-                          const char *auth_password,
-                          db_checkpassword_callback_t *callback,
-                          void (*request_callback)()) ATTR_NULL(3);
-
-#endif
diff --git a/src/auth/passdb-checkpassword.c b/src/auth/passdb-checkpassword.c
deleted file mode 100644 (file)
index b351b94..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
-
-#include "auth-common.h"
-#include "passdb.h"
-
-#ifdef PASSDB_CHECKPASSWORD 
-
-#include "password-scheme.h"
-#include "db-checkpassword.h"
-
-struct checkpassword_passdb_module {
-       struct passdb_module module;
-       struct db_checkpassword *db;
-};
-
-static void
-auth_checkpassword_callback(struct auth_request *request,
-                           enum db_checkpassword_status status,
-                           const char *const *extra_fields,
-                           verify_plain_callback_t *callback)
-{
-       const char *scheme, *crypted_pass = NULL;
-       unsigned int i;
-
-       switch (status) {
-       case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE:
-               callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
-               return;
-       case DB_CHECKPASSWORD_STATUS_FAILURE:
-               callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
-               return;
-       case DB_CHECKPASSWORD_STATUS_OK:
-               break;
-       }
-       for (i = 0; extra_fields[i] != NULL; i++) {
-               if (str_begins(extra_fields[i], "password=", &crypted_pass))
-                       ;
-               else if (extra_fields[i][0] != '\0') {
-                       auth_request_set_field_keyvalue(request,
-                                                       extra_fields[i], NULL);
-               }
-       }
-       if (crypted_pass != NULL) {
-               /* for cache */
-               scheme = password_get_scheme(&crypted_pass);
-               if (scheme != NULL) {
-                       auth_request_set_field(request, "password",
-                                              crypted_pass, scheme);
-               } else {
-                       e_error(authdb_event(request),
-                               "password field returned without {scheme} prefix");
-               }
-       }
-       callback(PASSDB_RESULT_OK, request);
-}
-
-static void
-checkpassword_verify_plain(struct auth_request *request, const char *password,
-                          verify_plain_callback_t *callback)
-{
-       struct passdb_module *_module = request->passdb->passdb;
-       struct checkpassword_passdb_module *module =
-               (struct checkpassword_passdb_module *)_module;
-
-       db_checkpassword_call(module->db, request, password,
-                             auth_checkpassword_callback, callback);
-}
-
-static void
-credentials_checkpassword_callback(struct auth_request *request,
-                                  enum db_checkpassword_status status,
-                                  const char *const *extra_fields,
-                                  lookup_credentials_callback_t *callback)
-{
-       const char *scheme, *crypted_pass = NULL;
-       unsigned int i;
-
-       switch (status) {
-       case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE:
-               callback(PASSDB_RESULT_INTERNAL_FAILURE, NULL, 0, request);
-               return;
-       case DB_CHECKPASSWORD_STATUS_FAILURE:
-               callback(PASSDB_RESULT_USER_UNKNOWN, NULL, 0, request);
-               return;
-       case DB_CHECKPASSWORD_STATUS_OK:
-               break;
-       }
-       for (i = 0; extra_fields[i] != NULL; i++) {
-               if (str_begins(extra_fields[i], "password=", &crypted_pass))
-                       ;
-               else if (extra_fields[i][0] != '\0') {
-                       auth_request_set_field_keyvalue(request,
-                                                       extra_fields[i], NULL);
-               }
-       }
-       scheme = password_get_scheme(&crypted_pass);
-       if (scheme == NULL)
-               scheme = request->wanted_credentials_scheme;
-
-       passdb_handle_credentials(PASSDB_RESULT_OK, crypted_pass, scheme,
-                                 callback, request);
-}
-
-static void
-checkpassword_lookup_credentials(struct auth_request *request,
-                                lookup_credentials_callback_t *callback)
-{
-       struct passdb_module *_module = request->passdb->passdb;
-       struct checkpassword_passdb_module *module =
-               (struct checkpassword_passdb_module *)_module;
-
-       db_checkpassword_call(module->db, request, NULL,
-                             credentials_checkpassword_callback, callback);
-}
-
-static struct passdb_module *
-checkpassword_preinit(pool_t pool, const char *args)
-{
-       struct checkpassword_passdb_module *module;
-       const char *checkpassword_path = args;
-       const char *checkpassword_reply_path =
-               PKG_LIBEXECDIR"/checkpassword-reply";
-
-       module = p_new(pool, struct checkpassword_passdb_module, 1);
-       module->db = db_checkpassword_init(checkpassword_path,
-                                          checkpassword_reply_path);
-       return &module->module;
-}
-
-static void checkpassword_deinit(struct passdb_module *_module)
-{
-       struct checkpassword_passdb_module *module =
-               (struct checkpassword_passdb_module *)_module;
-
-       db_checkpassword_deinit(&module->db);
-}
-
-struct passdb_module_interface passdb_checkpassword = {
-       "checkpassword",
-
-       checkpassword_preinit,
-       NULL,
-       checkpassword_deinit,
-
-       checkpassword_verify_plain,
-       checkpassword_lookup_credentials,
-       NULL
-};
-#else
-struct passdb_module_interface passdb_checkpassword = {
-       .name = "checkpassword"
-};
-#endif
index e15825caeca5fe0b20891d2eb106580902ca59e6..eb4ac8ae827f2d7ace11053d45565a679eef3796 100644 (file)
@@ -317,7 +317,6 @@ extern struct passdb_module_interface passdb_lua;
 #endif
 extern struct passdb_module_interface passdb_passwd_file;
 extern struct passdb_module_interface passdb_pam;
-extern struct passdb_module_interface passdb_checkpassword;
 extern struct passdb_module_interface passdb_ldap;
 extern struct passdb_module_interface passdb_sql;
 extern struct passdb_module_interface passdb_static;
@@ -335,7 +334,6 @@ void passdbs_init(void)
 #endif
        passdb_register_module(&passdb_passwd_file);
        passdb_register_module(&passdb_pam);
-       passdb_register_module(&passdb_checkpassword);
        passdb_register_module(&passdb_ldap);
        passdb_register_module(&passdb_sql);
        passdb_register_module(&passdb_static);
diff --git a/src/auth/userdb-checkpassword.c b/src/auth/userdb-checkpassword.c
deleted file mode 100644 (file)
index dea676d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
-
-#include "auth-common.h"
-#include "userdb.h"
-
-#ifdef USERDB_CHECKPASSWORD
-
-#include "db-checkpassword.h"
-
-struct checkpassword_userdb_module {
-       struct userdb_module module;
-       struct db_checkpassword *db;
-};
-
-static void
-userdb_checkpassword_callback(struct auth_request *request,
-                             enum db_checkpassword_status status,
-                             const char *const *extra_fields,
-                             userdb_callback_t *callback)
-{
-       unsigned int i;
-
-       switch (status) {
-       case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE:
-               callback(USERDB_RESULT_INTERNAL_FAILURE, request);
-               break;
-       case DB_CHECKPASSWORD_STATUS_FAILURE:
-               callback(USERDB_RESULT_USER_UNKNOWN, request);
-               break;
-       case DB_CHECKPASSWORD_STATUS_OK:
-               for (i = 0; extra_fields[i] != NULL; i++) {
-                       if (!str_begins_with(extra_fields[i], "userdb_"))
-                               continue;
-                       auth_request_set_field_keyvalue(request,
-                                                       extra_fields[i], NULL);
-               }
-               callback(USERDB_RESULT_OK, request);
-               break;
-       }
-}
-
-static void
-checkpassword_lookup(struct auth_request *request, userdb_callback_t *callback)
-{
-       struct userdb_module *_module = request->userdb->userdb;
-       struct checkpassword_userdb_module *module =
-               (struct checkpassword_userdb_module *)_module;
-
-       db_checkpassword_call(module->db, request, NULL,
-                             userdb_checkpassword_callback, callback);
-}
-
-static struct userdb_module *
-checkpassword_preinit(pool_t pool, const char *args)
-{
-       struct checkpassword_userdb_module *module;
-       const char *checkpassword_path = args;
-       const char *checkpassword_reply_path =
-               PKG_LIBEXECDIR"/checkpassword-reply";
-
-       module = p_new(pool, struct checkpassword_userdb_module, 1);
-       module->db = db_checkpassword_init(checkpassword_path,
-                                          checkpassword_reply_path);
-       return &module->module;
-}
-
-static void checkpassword_deinit(struct userdb_module *_module)
-{
-       struct checkpassword_userdb_module *module =
-               (struct checkpassword_userdb_module *)_module;
-
-       db_checkpassword_deinit(&module->db);
-}
-
-struct userdb_module_interface userdb_checkpassword = {
-       "checkpassword",
-
-       checkpassword_preinit,
-       NULL,
-       checkpassword_deinit,
-
-       checkpassword_lookup,
-
-       NULL,
-       NULL,
-       NULL
-};
-#else
-struct userdb_module_interface userdb_checkpassword = {
-       .name = "checkpassword"
-};
-#endif
index 738b6d623dd054c91675fd5e757a1958c233a3d9..0849659102895f4bc7abbf4168369d601e6ab38c 100644 (file)
@@ -226,7 +226,6 @@ extern struct userdb_module_interface userdb_passwd;
 extern struct userdb_module_interface userdb_passwd_file;
 extern struct userdb_module_interface userdb_ldap;
 extern struct userdb_module_interface userdb_sql;
-extern struct userdb_module_interface userdb_checkpassword;
 extern struct userdb_module_interface userdb_dict;
 #ifdef HAVE_LUA
 extern struct userdb_module_interface userdb_lua;
@@ -242,7 +241,6 @@ void userdbs_init(void)
        userdb_register_module(&userdb_static);
        userdb_register_module(&userdb_ldap);
        userdb_register_module(&userdb_sql);
-       userdb_register_module(&userdb_checkpassword);
        userdb_register_module(&userdb_dict);
 #ifdef HAVE_LUA
        userdb_register_module(&userdb_lua);
index 5b6246b05e01f022676a42e20823fb5c27516b31..b8d76cbdb20208d9162b97c1ce624285c5291259 100644 (file)
@@ -710,9 +710,6 @@ static void print_build_options(void)
 #ifdef PASSDB_BSDAUTH
                " bsdauth"
 #endif
-#ifdef PASSDB_CHECKPASSWORD
-               " checkpassword"
-#endif
 #ifdef PASSDB_LDAP
                " ldap"
 #endif
@@ -729,9 +726,6 @@ static void print_build_options(void)
                " sql"
 #endif
        "\nUserdb:"
-#ifdef USERDB_CHECKPASSWORD
-               " checkpassword"
-#endif
 #ifdef USERDB_LDAP
                " ldap"
 #ifndef BUILTIN_LDAP