## ProFTPD module `mod_auth_pam`

PAM stands for Pluggable Authentication Modules, and is used to configure ways for authenticating users. Now "authenticating" a user usually means comparing a password they give with some other information, and returning a "yes/no"-style answer. PAM does not provide all of the other information for a user, such as UID, GID, home, and shell. This means that `mod_auth_pam` cannot be used, by itself, as an auth module for `proftpd`; `mod_auth_pam` is used to supplement other auth modules by providing access to PAM's additional authentication checks.

Installation instructions for `mod_auth_pam` can be found here.

The most current version of `mod_auth_pam` is distributed in the ProFTPD source distribution.

## Directives

- AuthPAM
- AuthPAMConfig
- AuthPAMOptions

### AuthPAM

Syntax: AuthPAM on|off
Default: AuthPAM on
Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_auth_pam
Compatibility: 1.2.8rc2 and later

The `AuthPAM` directive enables or disables the module's runtime PAM check. If it is set to off this module does not consult PAM when authenticating a user.

### AuthPAMConfig

Syntax: AuthPAMConfig service
Default: AuthPAMConfig ftp
Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_auth_pam
Compatibility: 1.2.8rc2 and later

The `AuthPAMConfig` directive is used to specify the name of the service used when performing the PAM check; PAM configurations can vary depending on the service. By default, the "ftp" service is used. Note that on some platforms, e.g. FreeBSD, this may need to be set to "ftpd", depending on the PAM configuration involved.

Here's an example of changing the service used:

      <IfModule mod_auth_pam.c>
        AuthPAMConfig ftpd
      </IfModule>

### AuthPAMOptions

Syntax: AuthPAMOptions opt1 opt2 ... optN
Default: None
Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_auth_pam
Compatibility: 1.3.2rc1 and later

The `AuthPAMOptions` directive is used to configure various optional behavior of `mod_auth_pam`.

Example:

      <IfModule mod_auth_pam.c>
        # Do not set the PAM_TTY token when authenticating via PAM
        AuthPAMOptions NoTTY
      </IfModule>

The currently implemented options are:

- `NoTTY`

  By default, `mod_auth_pam` will use the `PAM_TTY` PAM API item, and will use a value of "/dev/ftpdPID". The item can be used by PAM modules for filtering access, for example. This "NoTTY" option tells `mod_auth_pam` to not set the `PAM_TTY` item.

  Note: On Solaris platforms, the use of this `PAM_TTY` token is mandatory, and cannot be disabled. This is due to Solaris Bug ID 4250887.

## Installation

The `mod_auth_pam` module is automatically included when `proftpd` is built on a system that supports PAM. To disable this automatic inclusion, use the `--disable-auth-pam` configure option.

## Usage

The following are some example platform-specific PAM configurations.

FreeBSD
To use PAM with ProFTPD, you must edit `/etc/pam.conf` (or `/etc/pam.d/ftpd`) and add the following lines, if they are not already present:

      ftpd auth    required    pam_unix.so         try_first_pass
      ftpd account required    pam_unix.so         try_first_pass
      ftpd session required    pam_permit.so

In your `proftpd.conf`, you will need to set `AuthPAMConfig` to use the above service name, i.e. "ftpd":

      <IfModule mod_auth_pam.c>
        AuthPAMConfig ftpd
      </IfModule>

PAM authentication should now work properly.

Linux
To use PAM with ProFTPD, you must edit `/etc/pam.d/ftp` and add the following lines for RedHat installations:

      #%PAM-1.0
      auth       required     /lib/security/pam_pwdb.so shadow nullok
      account    required     /lib/security/pam_pwdb.so
      session    required     /lib/security/pam_pwdb.so

For SuSE:

      #%PAM-1.0
      auth       required     /lib/security/pam_unix.so shadow nullok
      account    required     /lib/security/pam_unix.so
      session    required     /lib/security/pam_unix.so

These settings are valid for RedHat and SuSE Linux systems. Other Linux distributions may differ.

NOTE: If you are using a 64-bit system, you may need to change the above paths from "/lib/security/..." to "/lib64/security/...". Without this correction, on 64-bit systems, your ProFTPD logs may contain errors like:

      PAM unable to dlopen(/lib/security/pam_pwdb.so)
      PAM [dlerror: /lib/security/pam_pwdb.so: cannot open shared object file:
      No such file or directory]

After updating the paths in your `/etc/pam.d/ftp` file, be sure to restart ProFTPD, so that the new PAM configuration takes effect.

Mac OS X
To use PAM with ProFTPD, you must edit `/etc/pam.d/ftp` and add the following lines:

      auth       required    pam_unix.so try_first_pass
      account    required    pam_unix.so try_first_pass
      session    required    pam_permit.so

Or, if you are running Mac OSX 10.3 or later, you should have an `/etc/pam.d/ftpd` file that contains the following:

      auth       sufficient     pam_securityserver.so
      auth       required       pam_deny.so
      account    required       pam_permit.so
      password   required       pam_deny.so
      session    required       pam_permit.so

Then, in your `proftpd.conf`, use:

      <IfModule mod_auth_pam.c>
        AuthPAMConfig ftpd
      </IfModule>

Logging
The `mod_auth_pam` module supports trace logging, via the module-specific log channels:

- auth.pam

Thus for trace logging, to aid in debugging, you would use the following in your `proftpd.conf`:

      TraceLog /path/to/ftpd/trace.log
      Trace auth.pam:20

This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.

Frequently Asked Questions

Question: I am using `mod_auth_pam`, and in the system logs, I see the following messages for my ProFTPD sessions:

      proftpd[1654993]: pam_unix(proftpd:session): session opened for user paul by (uid=0)
      proftpd[1654993]: pam_systemd(proftpd:session): Failed to release session: Access denied
      proftpd[1654993]: pam_unix(proftpd:session): session closed for user paul

Is this a bug?

Answer: No, it is not a bug. It is a consequence of how ProFTPD manages root privileges, and (bad) assumptions made by the PAM API and libraries.

ProFTPD retains root privileges for a session only long enough to authenticate the user; this authentication does include opening a PAM session. After authentication completes, ProFTPD drops root privileges completely by default. This means that when that session completes, and the `mod_auth_pam` module uses the PAM API to close the session, the process no longer has the root privileges that the underlying PAM libraries need/want, hence the "Access denied" error.

This log message is benign, because it only occurs when the session process is ending anyway. You can change this by configuring ProFTPD to not drop root privileges after authentication -- although this is not recommended:

      # Do not revoke root privileges after authentication
      RootRevoke off

Question: I need to use PAM for enforcing the handling of aged/expired passwords on my Unix system. How do I make sure that PAM does the right thing?
Answer: For this sort of requirement, you are probably already using ProFTPD's default authentication modules, which include `mod_auth_unix` and `mod_auth_pam`. But to make sure that the PAM rules are enforced, you need to make `mod_auth_pam` be "authoritative", i.e. have the final say on whether a given password is acceptable. Use the `AuthOrder` directive to accomplish this, using:

      # It is important that mod_auth_pam appear before mod_auth_unix, and
      # that the asterisk appear after the name, not before.
      AuthOrder mod_auth_pam.c* mod_auth_unix.c

The asterisk ("*") after a module name in the `AuthOrder` directive is what tells `proftpd` to treat that module's results as authoritative.

© Copyright 2017-2020 The ProFTPD Project
All Rights Reserved