Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session

Classification:

compliance

Framework:

Control:

Description

To configure the number of retry prompts that are permitted per-session:

Edit the pam_pwquality.so statement in

/etc/pam.d/common-password to show

retry=3, or a lower value if site policy is more restrictive. The DoD requirement is a maximum of 3 prompts per session.

Rationale

Setting the password retry prompts that are permitted on a per-session basis to a low value requires some software, such as SSH, to re-connect. This can slow down and draw additional attention to some types of password-guessing attacks. Note that this is different from account lockout, which is provided by the pam_faillock module.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var\_password\_pam\_retry='3'


if [ -e "/etc/pam.d/common-password" ] ; then
 valueRegex="$var\_password\_pam\_retry" defaultValue="$var\_password\_pam\_retry"
 # non-empty values need to be preceded by an equals sign
 [ -n "${valueRegex}" ] && valueRegex="=${valueRegex}"
 # add an equals sign to non-empty values
 [ -n "${defaultValue}" ] && defaultValue="=${defaultValue}"

 # fix 'type' if it's wrong
 if grep -q -P "^\\s\*(?"'!'"password\\s)[[:alnum:]]+\\s+[[:alnum:]]+\\s+pam\_pwquality.so" < "/etc/pam.d/common-password" ; then
 sed --follow-symlinks -i -E -e "s/^(\\s\*)[[:alnum:]]+(\\s+[[:alnum:]]+\\s+pam\_pwquality.so)/\\1password\\2/" "/etc/pam.d/common-password"
 fi

 # fix 'control' if it's wrong
 if grep -q -P "^\\s\*password\\s+(?"'!'"requisite)[[:alnum:]]+\\s+pam\_pwquality.so" < "/etc/pam.d/common-password" ; then
 sed --follow-symlinks -i -E -e "s/^(\\s\*password\\s+)[[:alnum:]]+(\\s+pam\_pwquality.so)/\\1requisite\\2/" "/etc/pam.d/common-password"
 fi

 # fix the value for 'option' if one exists but does not match 'valueRegex'
 if grep -q -P "^\\s\*password\\s+requisite\\s+pam\_pwquality.so(\\s.+)?\\s+retry(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
 sed --follow-symlinks -i -E -e "s/^(\\s\*password\\s+requisite\\s+pam\_pwquality.so(\\s.+)?\\s)retry=[^[:space:]]\*/\\1retry${defaultValue}/" "/etc/pam.d/common-password"

 # add 'option=default' if option is not set
 elif grep -q -E "^\\s\*password\\s+requisite\\s+pam\_pwquality.so" < "/etc/pam.d/common-password" &&
 grep -E "^\\s\*password\\s+requisite\\s+pam\_pwquality.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\sretry(=|\\s|\$)" ; then

 sed --follow-symlinks -i -E -e "s/^(\\s\*password\\s+requisite\\s+pam\_pwquality.so[^\\n]\*)/\\1 retry${defaultValue}/" "/etc/pam.d/common-password"
 # add a new entry if none exists
 elif ! grep -q -P "^\\s\*password\\s+requisite\\s+pam\_pwquality.so(\\s.+)?\\s+retry${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
 echo "password requisite pam\_pwquality.so retry${defaultValue}" >> "/etc/pam.d/common-password"
 fi
else
 echo "/etc/pam.d/common-password doesn't exist" >&2
fi

else
 >&2 echo 'Remediation is not applicable, nothing was done'
fi