Description
Do not allow users to reuse recent passwords. This can be
accomplished by using the remember
option for the
pam_pwhistory
PAM modules.
In the file /etc/pam.d/common-password
, make sure the parameters
remember
and use_authtok
are present, and that the value
for the remember
parameter is 5 or greater. For example:
password requisite pam_pwhistory.so *...existing\_options...* remember=5 use_authtok
The DoD STIG requirement is 5 passwords.
Rationale
Preventing re-use of previous passwords helps ensure that a compromised password is not re-used by a user.
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
declare -a VALUES=()
declare -a VALUE\_NAMES=()
declare -a ARGS=()
declare -a NEW\_ARGS=()
var\_password\_pam\_remember='5'
VALUES+=("$var\_password\_pam\_remember")
VALUE\_NAMES+=("remember")
ARGS+=("")
NEW\_ARGS+=("")
VALUES+=("")
VALUE\_NAMES+=("")
ARGS+=("use\_authtok")
NEW\_ARGS+=("use\_authtok")
for idx in "${!VALUES[@]}"
do
if [ -e "/etc/pam.d/common-password" ] ; then
valueRegex="${VALUES[$idx]}" defaultValue="${VALUES[$idx]}"
# 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 the value for 'option' if one exists but does not match 'valueRegex'
if grep -q -P "^\\s\*password\\s+requisite\\s+pam\_pwhistory.so(\\s.+)?\\s+${VALUE\_NAMES[$idx]}(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
sed --follow-symlinks -i -E -e "s/^(\\s\*password\\s+requisite\\s+pam\_pwhistory.so(\\s.+)?\\s)${VALUE\_NAMES[$idx]}=[^[:space:]]\*/\\1${VALUE\_NAMES[$idx]}${defaultValue}/" "/etc/pam.d/common-password"
# add 'option=default' if option is not set
elif grep -q -E "^\\s\*password\\s+requisite\\s+pam\_pwhistory.so" < "/etc/pam.d/common-password" &&
grep -E "^\\s\*password\\s+requisite\\s+pam\_pwhistory.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\s${VALUE\_NAMES[$idx]}(=|\\s|\$)" ; then
sed --follow-symlinks -i -E -e "s/^(\\s\*password\\s+requisite\\s+pam\_pwhistory.so[^\\n]\*)/\\1 ${VALUE\_NAMES[$idx]}${defaultValue}/" "/etc/pam.d/common-password"
# add a new entry if none exists
elif ! grep -q -P "^\\s\*password\\s+requisite\\s+pam\_pwhistory.so(\\s.+)?\\s+${VALUE\_NAMES[$idx]}${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
echo "password requisite pam\_pwhistory.so ${VALUE\_NAMES[$idx]}${defaultValue}" >> "/etc/pam.d/common-password"
fi
else
echo "/etc/pam.d/common-password doesn't exist" >&2
fi
done
for idx in "${!ARGS[@]}"
do
if ! grep -q -P "^\s\*password\s+requisite\s+pam\_pwhistory.so.\*\s+${ARGS[$idx]}\s\*$" /etc/pam.d/common-password ; then
sed --follow-symlinks -i -E -e "s/^\\s\*password\\s+requisite\\s+pam\_pwhistory.so.\*\$/& ${NEW\_ARGS[$idx]}/" /etc/pam.d/common-password
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi