The pam_cracklib module's difok parameter controls requirements for
usage of different characters during a password change. The number of
changed characters refers to the number of changes required with respect to
the total number of positions in the current password. In other words,
characters may be the same within the two passwords; however, the positions
of the like characters must be different.
Make sure the difok parameter for the pam_cracklib module is
configured to greater than or equal to .
Rationale
Requiring a minimum number of different characters during password changes
ensures that newly changed passwords should not resemble previously
compromised ones. Note that passwords which are changed on compromised
systems will still be compromised, however.
declare -a VALUES=()
declare -a VALUE_NAMES=()
declare -a ARGS=()
declare -a NEW_ARGS=()
var_password_pam_difok='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_password_pam_difok" use="legacy"/>'
VALUES+=("$var_password_pam_difok")
VALUE_NAMES+=("difok")
ARGS+=("")
NEW_ARGS+=("")
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_cracklib.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_cracklib.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_cracklib.so" < "/etc/pam.d/common-password" &&
grep -E "^\\s*password\\s+requisite\\s+pam_cracklib.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_cracklib.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_cracklib.so(\\s.+)?\\s+${VALUE_NAMES[$idx]}${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
echo "password requisite pam_cracklib.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_cracklib.so.*\s+${ARGS[$idx]}\s*$" /etc/pam.d/common-password ; then
sed --follow-symlinks -i -E -e "s/^\\s*password\\s+requisite\\s+pam_cracklib.so.*\$/& ${NEW_ARGS[$idx]}/" /etc/pam.d/common-password
fi
done