This documentation is for Dovecot v2.x, see wiki1 for v1.x documentation.

CheckPassword

Checkpassword is an authentication interface originally implemented by qmail. Checkpassword combines both the password database and user database lookups into a single checkpassword lookup, which makes the standard implementation unsuitable for a standalone userdb. With Dovecot extensions it's also possible to use checkpassword as a userdb.

Typically you'll use prefetch as the userdb, but it's not required that you use the checkpassword script's userdb capabilities. You can still use for example static userdb if you're using only a single UID and GID, and your home directory fits into a template.

Security

The standard checkpassword design is incompatible with Dovecot's security model. If the system has local users and the checkpassword script setuid()s into a local user, the user is able to ptrace into the communication and change the authentication results. This is of course undesirable, so v2.2.7+ will just refuse to run in such environments by default. The possibilities to solve this are:

  1. If possible, change the checkpassword to return userdb_uid and userdb_gid extra fields instead of using setuid() and setgid(). This also improves the performance.

  2. If you can't change the script, you can make Dovecot's checkpassword-reply binary setuid or setgid (e.g. chgrp dovecot /usr/local/libexec/dovecot/checkpassword-reply; chmod g+s /usr/local/libexec/dovecot/checkpassword-reply)

  3. If you don't have any untrusted local users and you just don't care about this check, you can set INSECURE_SETUID=1 environment e.g. with a wrapper checkpassword script.

Deliver

If your checkpassword script doesn't support Dovecot extensions, you can't use it as a user database. This means that if you wish to use LDA, you can't use the -d parameter to do userdb lookups. There are two ways to solve this:

  1. Use another userdb which does the lookup for deliver, for example SQL or static. Add this userdb after the prefetch userdb.

  2. Use a script to look up the user's home directory and run deliver without -d parameter. For example:

#!/bin/sh

# <<Lookup user's home directory here.>>

# If users have different UIDs/GIDs, make sure to also change this process's UID and GID.
# If you want to override any settings, use dovecot-lda's -o parameter
# (e.g. dovecot-lda -o mail_location=maildir:~/Maildir).

export HOME
exec /usr/local/libexec/dovecot/dovecot-lda

Checkpassword Interface

The interface is specified in http://cr.yp.to/checkpwd/interface.html. However here's a quick tutorial for writing a script:

Qmail-LDAP

Note that auth_imap that comes with qmail-ldap is not compatible with this interface. You can get a patch that adds auth_dovecot functionality to qmail-ldap here. Or you can use auth_pop instead, but you may need to pass aliasempty to let auth_pop find the Maildir, so it is recommended to write a /var/qmail/bin/auth_dovecot wrapper (don't forget to chmod +x it) around auth_pop.

#!/bin/sh
QMAIL="/var/qmail"
if [ -e $QMAIL/control/defaultdelivery ]; then
    ALIASEMPTY=`head -n 1 $QMAIL/control/defaultdelivery 2> /dev/null`
else
    ALIASEMPTY=`head -n 1 $QMAIL/control/aliasempty 2> /dev/null`
fi
ALIASEMPTY=${ALIASEMPTY:-"./Maildir/"}
exec $QMAIL/bin/auth_pop "$@" $ALIASEMPTY

you can also use this wrapper to pass LOGLEVEL environmental variable to auth_pop.

Dovecot Extensions

If you wish to return extra fields for Dovecot, set them in environment variables and then list them in EXTRA environment variable. The userdb extra fields can be returned by prefixing them with userdb_. For example:

userdb_quota_rule=*:storage=10000
userdb_mail=mbox:$HOME/mboxes
EXTRA=userdb_quota_rule userdb_mail

Dovecot also sets some environment variables that the script may use:

Checkpassword as userdb

Dovecot calls the script with AUTHORIZED=1 environment set when performing a userdb lookup. The script must acknowledge this by changing the environment to AUTHORIZED=2, otherwise the lookup fails. Other than that, the script works the same way as a passdb checkpassword script. If user doesn't exist, use exit code 3.

Checkpassword with passdb lookups (v2.1.2+)

Normally checkpassword answers to questions "is user X's password Y?" This doesn't work with non-plaintext auth mechanisms, or when Dovecot wants to do a non-authenticating passdb lookup (e.g. for LMTP proxy). These passdb credentials lookups can be implemented the same way as a userdb lookup (i.e. change the AUTHORIZED environment).

Example

The standard way:

passdb {
  driver = checkpassword
  args = /usr/bin/checkpassword
}
userdb {
  driver = prefetch
}
# If you want to use deliver -d and your users are in SQL:
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

Using checkpassword only to verify the password:

passdb {
  driver = checkpassword
  args = /usr/bin/checkpassword
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/home/%u
}

Performance

The CheckPassword backend is not suited for heavy traffic. Especially if the script spawned have to launch an entire language interpreter.

If your user database is only accessible with custom code an alternative might be using the Dict AuthDatabase over a UNIX socket.

AuthDatabase/CheckPassword (last edited 2013-10-26 16:23:28 by TimoSirainen)