Home Blog Certs Knowledge Base About

LPIC-2 210.2 โ€” PAM Authentication

Exam topic 210.2 โ€” PAM Authentication (weight: 3). Covers PAM module types, control flags, key PAM modules, /etc/shadow format, nsswitch.conf, and SSSD integration.


What Is PAM

PAM (Pluggable Authentication Modules) is a set of libraries and APIs that gives applications a unified interface for authentication. Programs like login and su call the PAM API, and PAM handles where to verify the password โ€” /etc/shadow, LDAP, or elsewhere.

App1  โ”€โ”
App2  โ”€โ”คโ”€โ”€โ–บ PAM โ”€โ”€โ–บ pam_unix.so  โ”€โ”€โ–บ /etc/passwd, /etc/shadow
App3  โ”€โ”˜       โ””โ”€โ”€โ–บ pam_ldap.so  โ”€โ”€โ–บ LDAP server

Without PAM, each application would have to implement its own authentication code for every method.


Four Module Types

Every line in a PAM configuration belongs to one of four types:

TypePurpose
authVerifies the user is who they claim to be (password, token, etc.)
accountChecks account validity: password expiry, login allowed
passwordManages password changes
sessionActions at session open/close (logging, home directory mount, etc.)

Control Flags

The control flag determines what to do on module success or failure:

FlagOn failureOn success
requisiteImmediately stops with denialContinue processing
requiredRecords failure, continues checking other modulesContinue processing
sufficientContinue processingImmediately succeeds (if no prior required failures)
optionalIgnored if other modules existIgnored if other modules exist

Key exam distinction:

  • requisite โ€” instant failure, processing stops immediately
  • required โ€” records failure but continues all modules
  • sufficient โ€” instant success on pass

Configuration

Two configuration methods:

Method 1: single file /etc/pam.conf

service  type  control  module-path  module-arguments

Example:

login  auth  required  pam_unix.so

Method 2: directory /etc/pam.d/ (recommended)

Each service gets its own file named after the service: /etc/pam.d/login, /etc/pam.d/sshd, /etc/pam.d/su.

Same format but without the service field:

type  control  module-path  module-arguments

If /etc/pam.d/ directory exists, /etc/pam.conf is completely ignored.

On Debian/Ubuntu, common settings are in shared files: common-auth, common-account, common-password, common-session. Service configs include them via @include.

Example /etc/pam.d/login:

# Authentication via /etc/passwd and /etc/shadow
auth     required  pam_unix.so nullok

# Account state check (password expiry, etc.)
account  required  pam_unix.so

# Log session start and end
session  required  pam_unix.so

# Password change with min length 4, max 8
password required  pam_unix.so nullok obscure min=4 max=8

pam_unix

The standard module. Works with /etc/passwd and /etc/shadow. Supports all four types.

Useful arguments:

ArgumentDescription
nullokAllow empty passwords
try_first_passTry password from previous module, prompt only if it fails
use_first_passUse password from previous module, fail immediately if wrong
use_authtokUse the password set by the previous module (for password type)
remember=NRemember N last passwords, prevent reuse
md5Use MD5 instead of crypt()
debugLog via syslog
auditExtended syslog logging

The session type logs username and session type to syslog at start and end.


pam_nis

Authentication via NIS (Network Information Service). NIS is considered legacy and transmits data in plaintext. Modern replacement: LDAP/SSSD.

# /etc/pam.d/login โ€” NIS as primary, pam_unix as fallback
auth    sufficient pam_nis.so item=user sense=allow map=users.byname value=compsci
auth    required   pam_unix.so try_first_pass

account sufficient pam_ldap.so item=user sense=deny map=cancelled.byname error=expired
account required   pam_unix.so

pam_ldap

Direct authentication via LDAP without SSSD. The pam_ldap.so module contacts the LDAP server directly.

# /etc/pam.d/login
auth    sufficient pam_ldap.so
auth    required   pam_unix.so try_first_pass

account sufficient pam_ldap.so
account required   pam_unix.so

pam_ldap.so is simpler but doesn’t cache data โ€” if the server is unavailable, login fails. SSSD via pam_sss.so caches credentials and works offline.


pam_cracklib

Checks the strength of new passwords against dictionaries, compares with old password, checks complexity.

password required pam_cracklib.so difok=3 minlen=15 dcredit=2 ocredit=2
password required pam_unix.so use_authtok nullok md5
ArgumentDescription
minlen=NMinimum password length
difok=NMinimum N characters different from old password
dcredit=NCredit for digits (reduces minlen requirement)
ucredit=NCredit for uppercase letters
ocredit=NCredit for special characters
lcredit=NCredit for lowercase letters

pam_cracklib.so must come before pam_unix.so in the password block. Otherwise the password gets saved before the strength check.


pam_limits

Sets resource limits for user sessions. Works for uid=0 too.

Configuration from /etc/security/limits.conf and files in /etc/security/limits.d/.

session required pam_limits.so

Format of /etc/security/limits.conf:

# domain   type   item    value
*           soft   nofile  1024
*           hard   nofile  4096
@students   hard   nproc   20
john        hard   cpu     300

Limit types: soft (user can raise up to hard), hard (only root can change).

Common item values:

  • nofile โ€” open file count
  • nproc โ€” process count
  • cpu โ€” CPU time in minutes
  • maxlogins โ€” maximum concurrent sessions

pam_listfile

Allows or denies access based on a text file list. One entry per line.

auth required pam_listfile.so \
  item=user sense=allow file=/etc/allowed_users onerr=fail
ParameterDescription
itemWhat to check: user, tty, rhost, ruser, group, shell
senseallow โ€” allow only those in list; deny โ€” deny those in list
filePath to the list file
onerrWhat to do on file read error: succeed or fail

/etc/passwd and /etc/shadow

/etc/passwd โ€” public account information:

username:x:UID:GID:GECOS:home_dir:shell

The x field means the password is stored in /etc/shadow.

/etc/shadow โ€” protected file with password hashes (root-only):

username:$6$salt$hash:lastchg:min:max:warn:inactive:expire:

Shadow fields:

FieldDescription
lastchgLast password change (days since 1970-01-01)
minMinimum password age in days
maxMaximum password age in days
warnDays before expiry to warn
inactiveDays after expiry before lockout
expireAccount expiration date

Hash type prefix: $1$ = MD5, $5$ = SHA-256, $6$ = SHA-512.


nsswitch.conf

/etc/nsswitch.conf defines the order of data sources for various system databases. PAM uses it when checking users.

passwd:   files ldap
shadow:   files
group:    files ldap
hosts:    files dns

passwd: files ldap means: first look in /etc/passwd, then LDAP.

With SSSD:

passwd:   files sss
group:    files sss
shadow:   files sss

SSSD and LDAP

SSSD (System Security Services Daemon) is a middleware between PAM/NSS and network directories (LDAP, Active Directory). It caches credentials, allowing login even without network access.

PAM connects to SSSD via pam_sss.so.

SSSD setup for LDAP:

# Install (RHEL/CentOS)
yum install sssd sssd-ldap authconfig

# Configure via authconfig
authconfig \
  --enablesssd \
  --enablesssdauth \
  --enableldap \
  --enableldapauth \
  --ldapserver=ldap://ldap.example.com:389 \
  --ldapbasedn=dc=example,dc=com \
  --enablerfc2307bis \
  --enablemkhomedir \
  --enablecachecreds \
  --update

/etc/sssd/sssd.conf:

[sssd]
services = nss, pam
config_file_version = 2
domains = LDAP

[domain/LDAP]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldap://ldap.example.com:389
ldap_search_base = dc=example,dc=com
ldap_tls_cacertdir = /etc/pki/tls/cacerts
cache_credentials = true
chmod 600 /etc/sssd/sssd.conf    # required!
systemctl enable --now sssd

PAM configuration for SSSD:

# /etc/pam.d/system-auth
auth     sufficient pam_sss.so
auth     required   pam_unix.so try_first_pass
account  required   pam_unix.so
account  sufficient pam_sss.so
password sufficient pam_sss.so use_authtok
session  optional   pam_sss.so

Auto-create home directory on first login:

session optional pam_mkhomedir.so skel=/etc/skel umask=077

Exam Cheat Sheet

Files and Paths

PathPurpose
/etc/pam.confUnified PAM config (if /etc/pam.d/ doesn’t exist)
/etc/pam.d/Per-service config directory
/etc/passwdPublic account information
/etc/shadowPassword hashes (root only)
/etc/nsswitch.confNSS source order
/etc/security/limits.confResource limits for pam_limits
/etc/security/limits.d/Additional limits files
/etc/sssd/sssd.confSSSD configuration (must be chmod 600)

PAM Module Directory

DistributionPath
Debian/Ubuntu (64-bit)/lib/x86_64-linux-gnu/security/
RHEL/CentOS/Fedora/lib64/security/
Universal (legacy)/lib/security/

Key Modules

ModulePurpose
pam_unix.so/etc/passwd and /etc/shadow
pam_cracklib.soPassword strength checking
pam_limits.soResource limits from /etc/security/limits.conf
pam_listfile.soAllow/deny by file list
pam_ldap.soDirect LDAP authentication (no SSSD)
pam_sss.soAuthentication via SSSD
pam_deny.soAlways denies (safe fallback)
pam_mkhomedir.soCreates home on first login

Control Flags Summary

FlagFailureSuccess
requisiteImmediate stop + denyContinue
requiredMark failure, continueContinue
sufficientContinueImmediate stop + allow
optionalIgnoredIgnored

Config Line Format

# /etc/pam.conf
service  type  control  /lib/security/module.so  [args]

# /etc/pam.d/service_name
type  control  /lib/security/module.so  [args]

Common Pitfalls

PitfallRule
pam.conf + pam.d/ togetherpam.d/ completely overrides pam.conf
Missing 600 on sssd.confSSSD won’t start
pam_unix before pam_cracklib in password blockPassword saved before strength check
Forgetting pam_sss.so in all four typesSSSD partially won’t work