Applications need to check if the users are authorized. Instead of having this implemented in each application individually they can delegate it to PAM (Pluggable Authentication Modules). Applications that support PAM will find
always the same interface and use the libpam.so
library.
This allows by just editing the pam configuration files introduce different ways to identify the user as finger print, memory stick, remote login with different encryption methods without the need of re-compiling/configuring the application using pam.
See https://www.kernel.org/pub/linux/libs/pam/
Since every application using pam has a configuration file in the directory /etc/pam.d
ls /stc/pam.d list all applications using pam.
Some configuration files are used/included by other configuration files and are therefore not linked to a single application.
If an application does not find its matching file it uses the default file
/etc/pam.d/other
. This file should be present and
deny every access.
To check if a program (application) support pam check if it uses the pam library that is used as interface to pam
ldd<name of the program>
| grep libpam.so
Example:
ldd /bin/login | grep libpam.so
libpam.so.0 => /lib64/libpam.so.0 (0x00007f7752f88000)
Pam has modules for the authentication method. Documentation about those modules
can be found under /usr/share/doc/pam-1.2.1-r2/modules
. The modules itself are under
/lib/security
and as it can be observed there, the pam
modules are shared object libraries. They have names as pam_
and some
have
even manual pages so man pam_<name>
.so<name>
.so pops up a description.
To see what a module support, go to /lib/security
and type:
nm --dynamic --defined-only pam_<name>
.so
The /etc/pam.d
files are structured as a spreadsheet having columns and rows.
The first column in the /etc/pam.d
files contains what the application wants from pam. pam (or the pam modules) can support the following:
auth (Example: Verify that a user has entered the correct password)
account (Example: Check if the user is allowed to do this task)
password (Example: Check if the password is not too simple)
session (Example: Doing things before and after login as mounting or logging)
The next column is called the controlflag and defines how the rows (modules) are stacked together. It can be:
required |
A failure will lead to failure but only after the remaining rows are processed. |
requisite |
The row must pass. It returns immediately when failed |
sufficient |
If it passes PAM immediately passes without calling the next modules, It is allowed to fail |
optional |
Is allowed to fail except if it is the only one |
include |
Includes all lines of an other |
substack |
As include, but just for a group of lines |
Additionally to the above controlflags there is an alternative syntax using a term in brackets [] where more detailed controlflags can be defined.
The next column is the module that is used followed by a column where options to the module can be passed. Common options might be: debug, use_mapped_pass and use_first_pass.
The files in /etc/pam.d
hold the rules for the
authentication and make use of the modules in /lib/security
. The files in /etc/pam.d
have a rule per line.
To be more flexible different lines can be stacked together so they get sequentially read until the
authentication shows the result pass or failed.
It is important to understand the different parties involved in PAM:
Application making use of pam e.g. requests authentication and calls libpam.so
libpam.so
reads the pam configuration files /etc/pam.d
setting up
the rules for authentication
libpam.so
starts the pam modules that are shared object files in /lib/security
/etc/pam.d/passwd
auth sufficient pam_rootok.so
Passes and returns if the the user is root. It does not fail if it is not root but continues with the following row.
auth include system-auth
It does not call an other pam module (so library) but processes the /etc/pam.d/system-auth
pam config file.