CheckPassword
=============

Checkpassword is an authentication interface originally implemented by qmail
[http://www.qmail.org/]. Checkpassword combines both the <password database>
[PasswordDatabase.txt] and <user database> [UserDatabase.txt] lookups into a
single checkpassword lookup, which makes it unsuitable for a standalone user
database.

Typically you'll use <prefetch> [UserDatabase.Prefetch.txt] 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> [UserDatabase.Static.txt] if
you're using only a single UID and GID, and your home directory fits into a
template.

Deliver
-------

As mentioned above, checkpassword can't be used as a user database. This means
that if you wish to use<deliver> [LDA.txt], 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>
    [AuthDatabase.SQL.txt] or <static> [UserDatabase.Static.txt]. 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. Note that only HOME environment is passed
# to deliver, you can't set MAIL or anything else.

export HOME
exec /usr/local/libexec/dovecot/deliver
---%<-------------------------------------------------------------------------

Checkpassword Interface
-----------------------

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

 * Read '<username> NUL <password> NUL' from fd 3.
 * Verify the username and password.
    * If the authentication fails, exit with code 1. This makes Dovecot give
      "Authentication failed" error to user.
    * If you encounter an internal error, exit with code 111. This makes
      Dovecot give "Temporary authentication failure" error to user.
 * If the authentication succeeds, you'll need to:
    * Set user's home directory to '$HOME' environment. This isn't required,
      <but highly encouraged> [VirtualUsers.txt].
    * Set '$USER' environment variable. If the user name was changed (eg. if
      you lowercased "Username" to "username"), you can tell about it to
      Dovecot by setting '$USER' to the changed user name.
    * Change the process's effective UID and GID to the user's <UNIX UID and
      GID> [UserIds.txt].
       * Alternatively you could set 'userdb_uid' and 'userdb_gid' environments
         and add them to 'EXTRA' environment (see below for Dovecot
         extensions).
    * Your program received a path to 'checkpassword-reply' binary as the first
      parameter. Execute it.

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
[http://japc.uncovering.org/dovecot/qmail-ldap-1.03-20060201-dovecot.patch]. 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> [PasswordDatabase.ExtraFields.txt] for
Dovecot, set them in environment variables and then list them in EXTRA
environment variable. The<userdb extra fields> [UserDatabase.ExtraFields.txt]
can be returned by prefixing them with 'userdb_'. For example:

---%<-------------------------------------------------------------------------
userdb_quota=maildir:storage=10000
userdb_mail=mbox:$HOME/mboxes
EXTRA=userdb_quota userdb_mail
---%<-------------------------------------------------------------------------

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

 * 'SERVICE': contains eg. imap, pop3 or smtp
 * 'TCPLOCALIP' and 'TCPREMOTEIP': Client socket's IP addresses if available
 * 'MASTER_USER': If master login is attempted. This means that the password
   contains the master user's password and the normal username contains the
   user who master wants to log in as.

Example
-------

The standard way:

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

Using checkpassword only to verify the password:

---%<-------------------------------------------------------------------------
passdb checkpassword {
  args = /usr/bin/checkpassword
}
userdb static {
  args = uid=500 gid=500 home=/home/%u
}
---%<-------------------------------------------------------------------------

(This file was created from the wiki on 2008-06-20 04:42)
