Fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' breaks `passwd`
Description of problem:
Fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' breaks passwd
SCAP Security Guide Version:
Benchmark Version: 0.1.73
Operating System Version:
Ubuntu 22.04.4 LTS
Steps to Reproduce:
Execute Bash Remediation Script for CIS Ubuntu 22.04 Level 1 Server Benchmark
###############################################################################
# BEGIN fix (42 / 291) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 42/291: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# 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
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
Actual Results:
Remediating rule 42/291: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
# passwd
passwd: Module is unknown
passwd: password unchanged
Expected Results:
# passwd
New password:
Retype new password:
CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v1.0.0_5.4.1.pdf CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v2.0.0_5.4.1.pdf
Could you paste more information since I can't reproduce on latest commit of master branch. Here is my generated remediation which is exactly the same:
###############################################################################
# BEGIN fix (44 / 293) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# 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
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
@alanmcanonical, did you run passwd as root?
FYI: commit: f0c15b27298fd27cc6f9fd5171f81575d7751a5e
build command:
export ADDITIONAL_CMAKE_OPTIONS="-DSSG_SCE_ENABLED:BOOL=ON"
./build_product -j8 ubuntu2204 -o'5.11'
generate the remediation:
cd build
oscap xccdf generate fix --profile cis_level1_server --cpe ssg-ubuntu2204-cpe-dictionary.xml --verbose INFO --verbose-log-file verbose.log --output fix.sh ssg-ubuntu2204-xccdf.xml
Clear install ubuntu-22.04.4-live-server-amd64. Lets use your https://github.com/ComplianceAsCode/content/issues/12074#issuecomment-2195994583 script
root@ad:/home/ad# nano xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
root@ad:/home/ad# chmod +x xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
# before (I entered mismatched passwords here on purpose)
root@ad:/home/ad# passwd
New password:
Retype new password:
Sorry, passwords do not match.
passwd: Authentication token manipulation error
passwd: password unchanged
root@ad:/home/ad# ./xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
# after
root@ad:/home/ad# passwd
passwd: Module is unknown
passwd: password unchanged
root@ad:/home/ad# cat xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
###############################################################################
# BEGIN fix (44 / 293) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# 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
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
root@ad:/home/ad# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
root@ad:/home/ad# history
1 nano xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
2 chmod +x xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
3 passwd
4 ./xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
5 passwd
6 cat xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
7 cat /etc/os-release
8 history
@PiRomant do you have libpam-pwquality installed?
There is no libpam-pwquality after running the script https://github.com/ComplianceAsCode/content/issues/12074#issuecomment-2195994583.
I don't have libpam-pwquality too
So, there are 7 pam_pwquality configuration checks, and none of them confirms that it is installed and enabled?
There is no
libpam-pwqualityafter running the script #12074 (comment).
Try installing it, it is part of the whole CIS 5.4.1 solution. Does it solve your issue?
Yes, it helps. After installing libpam-pwqualit, none of the remediation below break passwd.
However, password restrictions do not apply to root. Root can set a weak password for anyone.
'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minclass' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'
Yes, it helps. After installing
libpam-pwqualit, none of the remediation below breakpasswd. However, password restrictions do not apply to root. Root can set a weak password for anyone.'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minclass' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'
I believe that's by design, if you want root to also follow the same guidelines, you would need to use the enforce_for_root
https://linux.die.net/man/8/pam_pwquality
Yes, and this both now in CIS v2.
CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v2.0.0_5.3.1.3 Ensure libpam-pwquality is installed CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v2.0.0_5.3.3.2.8 Ensure password quality is enforced for the root user
Yes, and this both now in CIS v2.
CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v2.0.0_5.3.1.3 Ensure libpam-pwquality is installed CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v2.0.0_5.3.3.2.8 Ensure password quality is enforced for the root user
the ubuntu profile is for now still in v1.
Since this is not an issue I'm closing it.
But, installing libpam-pwquality is a part of 5.4.1 in v1. https://github.com/user-attachments/files/15899704/CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v1.0.0_5.4.1.pdf
@PiRomant that is already part of the remediation and profile: https://github.com/ComplianceAsCode/content/blob/master/products/ubuntu2204/profiles/cis_level1_server.profile#L850
It probably just isn't part of version 0.1.73, it will land in the next one
if you need more information: https://github.com/ComplianceAsCode/content/pull/11968