PAM - Pluggable Authentication Modules
======================================

This is the most common way to authenticate system users nowadays. PAM is not
itself a password database, but rather its configuration tells the system how
exactly to do the authentication. Usually this means using the 'pam_unix.so'
module, which authenticates user from the system's shadow password file.

Because PAM is not an actual database, only plaintext authentication mechanisms
can be used with PAM. PAM cannot be used as a user database either (although
static user templates could be used to provide the same effect). Usually PAM is
used with <passwd> [AuthDatabase.Passwd.txt] (NSS) or <static>
[UserDatabase.Static.txt] user databases.

Dovecot should work with Linux PAM, Solaris PAM, OpenPAM (FreeBSD) and ApplePAM
(Mac OS X).

Service name
------------

The PAM configuration is usually in the '/etc/pam.d/' directory, but some
systems may use a single file,'/etc/pam.conf'. By default Dovecot uses
'dovecot' as the PAM service name, so the configuration is read from
'/etc/pam.d/dovecot'. You can change this by giving the wanted service name in
the 'args' parameter. You can also set the service to '*' in which case Dovecot
automatically uses either 'imap' or 'pop3' as the service, depending on the
actual service the user is logging in to. Here are a few examples:

---%<-------------------------------------------------------------------------
passdb pam {
  # use /etc/pam.d/imap and /etc/pam.d/pop3
  args = *
}
---%<-------------------------------------------------------------------------

---%<-------------------------------------------------------------------------
passdb pam {
  # use /etc/pam.d/mail
  args = mail
}
---%<-------------------------------------------------------------------------

PAM sessions
------------

By giving a 'session=yes' parameter, you can make Dovecot open a PAM session
and close it immediately. Some PAM plugins need this, for instance
'pam_mkhomedir'. With this parameter, 'dovecot.conf' might look something like
this:

---%<-------------------------------------------------------------------------
passdb pam {
  args = session=yes dovecot
}
---%<-------------------------------------------------------------------------

PAM credentials
---------------

By giving a 'setcred=yes' parameter, you can make Dovecot create PAM
credentials. Some PAM plugins need this. The credentials are never deleted
however, so using this might cause problems with other PAM plugins.

Non-forking PAM lookups (v1.0-only)
-----------------------------------

Note that v1.1+ uses this by default.

By default Dovecot v1.0's dovecot-auth forks a new process for each PAM lookup,
which is then destroyed after the lookup is done. This may have some problems
however because the forked processes share all the file descriptors with the
parent process. For example if you're using nss_ldap and your PAM plugin does a
NSS lookup, it's entirely possible that two PAM child processes are using the
same LDAP connection to do the lookup at the same time and they get their
replies mixed, causing wrong user's information to be used.

Setting 'blocking=yes' uses the alternative way: dovecot-auth worker processes
do the PAM lookups. See the next section for problems with this.

---%<-------------------------------------------------------------------------
passdb pam {
  # v1.0 only:
  args = blocking=yes
}
---%<-------------------------------------------------------------------------

Limiting the number of PAM lookups
----------------------------------

Dovecot v1.1+ or v1.0 with 'blocking=yes' enabled uses auth worker processes to
do PAM lookups. Usually PAM is used to do only a single lookup in a process, so
this may cause memory leaks in PAM plugins or maybe other problems. If you
notice that PAM authentication stops working after some time, you can limit the
number of lookups done by the auth worker process before it dies:

---%<-------------------------------------------------------------------------
# v1.1:
auth_worker_max_request_count = 100

# v1.2+:
passdb pam {
  args = max_requests = 100
}
---%<-------------------------------------------------------------------------

Note that v1.1's 'auth_worker_max_request_count' applies to all lookups, not
just PAM lookups. So for example if you've configured Dovecot to use both PAM
and MySQL, both of the lookups are done in the same auth worker processes and
both of them are counted as requests. This is never really wanted, which is why
this was changed in v1.2.

Username changing
-----------------

A PAM module can change the username. This requires either Dovecot v1.1+ or
'blocking=yes' with v1.0.

Making PAM plugin failure messages visible
------------------------------------------

You can replace the default "Authentication failed" reply with PAM's failure
reply by setting:

---%<-------------------------------------------------------------------------
passdb pam {
  args = failure_show_msg=yes
}
---%<-------------------------------------------------------------------------

This can be useful with e.g. pam_opie to find out which one time password
you're supposed to give:

---%<-------------------------------------------------------------------------
1 LOGIN username otp
1 NO otp-md5 324 0x1578 ext, Response:
---%<-------------------------------------------------------------------------

Caching
-------

Dovecot supports caching password lookups by setting 'auth_cache_size' to
non-zero value. For this to work with PAM, you'll also have to give 'cache_key'
parameter. Usually the user is authenticated only based on the username and
password, but PAM plugins may do all kinds of other checks as well, so this
can't be relied on. For this reason the 'cache_key' must contain all the
<variables> [Variables.txt] that may affect authentication. The commonly used
variables are:

 * '%u' - Username. You'll most likely want to use this.
 * '%s' - Service. If you use '*' as the service name you'll most likely want
   to use this.
 * '%r' - Remote IP address. Use this if you do any IP related checks.
 * '%l' - Local IP address. Use this if you do any checks based on the local IP
   address that was connected to.

Examples:

---%<-------------------------------------------------------------------------
# 1MB auth cache size
auth_cache_size = 1024
passdb pam {
  # username and service
  args = cache_key=%u%s *
}
---%<-------------------------------------------------------------------------

---%<-------------------------------------------------------------------------
# 1MB auth cache size
auth_cache_size = 1024
passdb pam {
  # username, remote IP and local IP
  args = cache_key=%u%r%l dovecot
}
---%<-------------------------------------------------------------------------

Examples
--------

Linux
-----

Here is an example '/etc/pam.d/dovecot' configuration file which uses standard
UNIX authentication:

---%<-------------------------------------------------------------------------
auth    required        pam_unix.so nullok
account required        pam_unix.so
---%<-------------------------------------------------------------------------

Solaris
-------

For Solaris you will have to edit '/etc/pam.conf'. Here is a working Solaris
example (using 'args = *' instead of the default 'dovecot' service):

---%<-------------------------------------------------------------------------
imap    auth    requisite       pam_authtok_get.so.1
imap    auth    required       pam_unix_auth.so.1
imap    account requisite       pam_roles.so.1
imap    account required        pam_unix_account.so.1
imap    session required        pam_unix_session.so.1
pop3   auth    requisite   pam_authtok_get.so.1
pop3   auth    required    pam_unix_auth.so.1
pop3   account requisite   pam_roles.so.1
pop3   account required    pam_unix_account.so.1
pop3   session required    pam_unix_session.so.1
---%<-------------------------------------------------------------------------

Mac OS X
--------

On Mac OS X, the '/etc/pam.d/dovecot' file should look like this:

---%<-------------------------------------------------------------------------
auth       required       pam_nologin.so
auth       sufficient     pam_securityserver.so
auth       sufficient     pam_unix.so
auth       required       pam_deny.so
account    required       pam_permit.so
password   required       pam_deny.so
session    required       pam_uwtmp.so
---%<-------------------------------------------------------------------------

...which, as the equivalent of '/etc/pam.d/login' on OS X 10.4, can be
represented as the following on that OS:

---%<-------------------------------------------------------------------------
passdb pam {
  args = login
}
---%<-------------------------------------------------------------------------

On Mac OS X, "passwd" can be used as a userdb to fill in UID, GID, and homedir
information after PAM was used as a passdb, even though Directory Services
prevents "passdb passwd" from working as a username/password authenticator. 
This will provide full system user authentication with true homedir mail
storage, without resorting to a single virtual mail user or LDAP:

---%<-------------------------------------------------------------------------
userdb passwd {
  args =
}
---%<-------------------------------------------------------------------------

(This file was created from the wiki on 2010-05-24 04:42)
