PAM (Pluggable Authentication Modules)
PAM is a system for configuring authentication (login) on Linux systems as well as several others.
It includes many modules to configure the system to authenticate against various databases, including the passwd file, kerberos, and many others.
PAM authentication consists of four basic parts:
This examines whether the user's password is correct.
This examines whether the user's account is valid, including expiration and time restrictions
Password changing (password)
This controls how users change their passwords.
This does setup for a user session, such as announcing last login, checking if any mail is available, and/or creating a home directory.
Any particular service may check all of these parts or just a subset (or none at all, but that's out side the scope of this document)
Here is an attempt to set up PAM to use every module possible, in the "best" (hah!) way. Successful authentication by any method should allow login. Example is based on Debian/Ubuntu, but should be applicable to any distribution
#display the file /etc/issue before login auth required pam_issue.so # only allow root login from ttys listed in /etc/securetty auth requisite pam_securetty.so # only allow root login if /etc/nologin exists auth requisite pam_nologin.so # include other auth methods common to all services @include common-auth # grant additional group access beyond /etc/group auth optional pam_group.so
# only allow logins during time configured in /etc/security/time.conf account requisite pam_time.so # only allow logins to certain users from certain hosts or ttys account required pam_access.so # include other account methods common to all services @include common-account
# set limits on system resource usage (memory, files, CPU time) session required pam_limits.so # display the last login time session optional pam_lastlog.so # display the message of the day (/etc/motd session optional pam_motd.so # display a message if mail is waiting session optional pam_mail.so standard # set the selinux security context session required pam_selinux.so multiple # include other session methods common to all services @include common-session
# include password-change methods common to all services @include common-password
account sufficient pam_krb5.so account required pam_unix.so
# lock non-root users out for a time if they fail to log in 10 times. Lock them out for 30 seconds. Might be a potential DoS vector, especially if you use it with a remotely-accessible service. auth required pam_tally.so deny=10 unlock_time=30 lock_time=30 # try to authenticate against kerberos. If that fails, skip openafs because it requires a kerberos ticket to work. try_first_pass is not really necessary. auth [success=ok new_authtok_reqd=ok ignore=ignore default=1] pam_krb5.so try_first_pass # try to get openafs token. Even if we can't get it, if we got here we're done because krb5 must have worked. auth [default=done] pam_openafs_session.so # Try to use the OpenPGP smartcard. Too bad it doesn't allow try_first_pass. auth sufficient pam_poldi.so quiet # Try to authenticate against /etc/passwd. auth sufficient pam_unix.so nullok_secure try_first_pass md5 shadow # Else we fail. This is not really necessary, but if it's not here the last module above needs to be "required" instead of "sufficient" auth required pam_deny.so
# Password quality checker password requisite pam_cracklib.so # or another one password requisite pam_passwdqc.so # Try to change kerberos password, but don't sweat it if we can't because user might have entered their UNIX password. If it does work though, just change it to the one that pam_passwdqc gave us. password [default=reset] pam_krb5.so use_authtok try_first_pass # Try to change smartcard PIN. Doesn't work because poldi doesn't implement this [yet] #password required pam_poldi.so # Try to change UNIX password to the one that pam_passwdqc gave us. password required pam_unix.so try_first_pass use_authtok nullok obscure min=4 max=8 md5
Note: this part doesn't work well. It's virtually impossible to get PAM to change passwords properly if you have more than one authentication service.
What should happen: PAM asks for a password for kerberos. If it's correct, use some other module such as pam_passwdqc or pam_cracklib to prompt for a new password. Update the kerberos password with the one accepted by the quality checker. Try the same old password against the next module. If it fails, ask for the old password for this module. If that one succeeds, use it to update that service's password with the qc-accepted password. Continue through the password stack. At the end, report which modules succeeded and which failed.
What shouldn't happen: PAM asks for a password. Fail because a module doesn't support password changing.
What else shouldn't happen: PAM asks for a password. If it's correct for the second module, prompt for a new password for the first module. Fail because the old password for the second module is not correct for the first module.
Another thing that shouldn't happen: PAM looks at the auth stack when running through the password stack.
session required pam_unix.so session optional pam_foreground.so
List of pam modules
Supplied with stock PAM