Blame SOURCES/scap-security-guide-0.1.61-pwquality-PR_8185.patch

38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml
38a2c0
new file mode 100644
38a2c0
index 00000000000..b44c91cbf4a
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml
38a2c0
@@ -0,0 +1,150 @@
38a2c0
+# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel
38a2c0
+# reboot = false
38a2c0
+# strategy = configure
38a2c0
+# complexity = low
38a2c0
+# disruption = medium
38a2c0
+
38a2c0
+- name: Check for existing pam_pwquality.so entry
38a2c0
+  ansible.builtin.lineinfile:
38a2c0
+    path: "/etc/pam.d/password-auth"
38a2c0
+    create: no
38a2c0
+    regexp: '^password.*pam_pwquality.so.*'
38a2c0
+    state: absent
38a2c0
+  check_mode: true
38a2c0
+  changed_when: false
38a2c0
+  register: result_pam_pwquality_present
38a2c0
+
38a2c0
+- name: Check if system relies on authselect
38a2c0
+  ansible.builtin.stat:
38a2c0
+    path: /usr/bin/authselect
38a2c0
+  register: result_authselect_present
38a2c0
+
38a2c0
+- name: "Remediation where authselect tool is present"
38a2c0
+  block:
38a2c0
+    - name: Check the integrity of the current authselect profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect check
38a2c0
+      register: result_authselect_check_cmd
38a2c0
+      changed_when: false
38a2c0
+      ignore_errors: true
38a2c0
+
38a2c0
+    - name: Informative message based on the authselect integrity check result
38a2c0
+      ansible.builtin.assert:
38a2c0
+        that:
38a2c0
+          - result_authselect_check_cmd is success
38a2c0
+        fail_msg:
38a2c0
+        - authselect integrity check failed. Remediation aborted!
38a2c0
+        - This remediation could not be applied because the authselect profile is not intact.
38a2c0
+        - It is not recommended to manually edit the PAM files when authselect is available.
38a2c0
+        - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended.
38a2c0
+        success_msg:
38a2c0
+        - authselect integrity check passed
38a2c0
+
38a2c0
+    - name: Get authselect current profile
38a2c0
+      ansible.builtin.shell:
38a2c0
+        cmd: authselect current -r | awk '{ print $1 }'
38a2c0
+      register: result_authselect_profile
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+
38a2c0
+    - name: Define the current authselect profile as a local fact
38a2c0
+      ansible.builtin.set_fact:
38a2c0
+        authselect_current_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+        authselect_custom_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_profile.stdout is match("custom/")
38a2c0
+
38a2c0
+    - name: Define the new authselect custom profile as a local fact
38a2c0
+      ansible.builtin.set_fact:
38a2c0
+        authselect_current_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+        authselect_custom_profile: "custom/hardening"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_profile.stdout is not match("custom/")
38a2c0
+
38a2c0
+    - name: Get authselect current features to also enable them in the custom profile
38a2c0
+      ansible.builtin.shell:
38a2c0
+        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
38a2c0
+      register: result_authselect_features
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+
38a2c0
+    - name: Check if any custom profile with the same name was already created in the past
38a2c0
+      ansible.builtin.stat:
38a2c0
+        path: /etc/authselect/{{ authselect_custom_profile }}
38a2c0
+      register: result_authselect_custom_profile_present
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+
38a2c0
+    - name: Create a custom profile based on the current profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect create-profile hardening -b sssd
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - not result_authselect_custom_profile_present.stat.exists
38a2c0
+
38a2c0
+    - name: Ensure the desired configuration is present in the custom profile
38a2c0
+      ansible.builtin.lineinfile:
38a2c0
+        dest: "/etc/authselect/{{ authselect_custom_profile }}/password-auth"
38a2c0
+        insertbefore: ^password.*sufficient.*pam_unix.so.*
38a2c0
+        line: "password    requisite                                    pam_pwquality.so"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_pam_pwquality_present.found == 0
38a2c0
+
38a2c0
+    - name: Ensure a backup of current authselect profile before selecting the custom profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect apply-changes -b --backup=before-pwquality-hardening.backup
38a2c0
+      register: result_authselect_backup
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - authselect_custom_profile is not match(authselect_current_profile)
38a2c0
+
38a2c0
+    - name: Ensure the custom profile is selected
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect select {{ authselect_custom_profile }} --force
38a2c0
+      register: result_pam_authselect_select_profile
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - authselect_custom_profile is not match(authselect_current_profile)
38a2c0
+
38a2c0
+    - name: Restore the authselect features in the custom profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect enable-feature {{ item }}
38a2c0
+      loop: "{{ result_authselect_features.stdout_lines }}"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_features is not skipped
38a2c0
+        - result_pam_authselect_select_profile is not skipped
38a2c0
+
38a2c0
+    - name: Ensure the custom profile changes are applied
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect apply-changes -b --backup=after-pwquality-hardening.backup
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+  when:
38a2c0
+  - result_authselect_present.stat.exists
38a2c0
+
38a2c0
+# For systems without authselect
38a2c0
+- name: "Remediation where authselect tool is not present and PAM files are directly edited"
38a2c0
+  block:
38a2c0
+    - name: Ensure the desired configuration is present in the custom profile
38a2c0
+      ansible.builtin.lineinfile:
38a2c0
+        dest: "/etc/pam.d/password-auth"
38a2c0
+        insertbefore: ^password.*sufficient.*pam_unix.so.*
38a2c0
+        line: "password    requisite                                    pam_pwquality.so"
38a2c0
+      when:
38a2c0
+        - result_pam_pwquality_present.found == 0
38a2c0
+  when:
38a2c0
+    - not result_authselect_present.stat.exists
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..d2fca2a79ca
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh
38a2c0
@@ -0,0 +1,41 @@
38a2c0
+# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel
38a2c0
+
38a2c0
+PAM_FILE="password-auth"
38a2c0
+
38a2c0
+if [ -f /usr/bin/authselect ]; then
38a2c0
+    if authselect check; then
38a2c0
+        CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
38a2c0
+        # Standard profiles delivered with authselect should not be modified.
38a2c0
+        # If not already in use, a custom profile is created preserving the enabled features.
38a2c0
+        if [[ ! $CURRENT_PROFILE == custom/* ]]; then
38a2c0
+            ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
38a2c0
+            authselect create-profile hardening -b $CURRENT_PROFILE
38a2c0
+            CURRENT_PROFILE="custom/hardening"
38a2c0
+            # Ensure a backup before changing the profile
38a2c0
+            authselect apply-changes -b --backup=before-pwquality-hardening.backup
38a2c0
+            authselect select $CURRENT_PROFILE
38a2c0
+            for feature in $ENABLED_FEATURES; do
38a2c0
+                authselect enable-feature $feature;
38a2c0
+            done
38a2c0
+        fi
38a2c0
+        # Include the desired configuration in the custom profile
38a2c0
+        CUSTOM_FILE="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE"
38a2c0
+        # The line should be included on the top password section
38a2c0
+		if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_FILE) -eq 0 ]; then
38a2c0
+  		  sed -i --follow-symlinks '0,/^password.*/s/^password.*/password    requisite                                    pam_pwquality.so\n&/' $CUSTOM_FILE
38a2c0
+		fi
38a2c0
+        authselect apply-changes -b --backup=after-pwquality-hardening.backup
38a2c0
+    else
38a2c0
+        echo "
38a2c0
+authselect integrity check failed. Remediation aborted!
38a2c0
+This remediation could not be applied because the authselect profile is not intact.
38a2c0
+It is not recommended to manually edit the PAM files when authselect is available.
38a2c0
+In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
38a2c0
+        false
38a2c0
+    fi
38a2c0
+else
38a2c0
+    FILE_PATH="/etc/pam.d/$PAM_FILE"
38a2c0
+    if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $FILE_PATH) -eq 0 ]; then
38a2c0
+        sed -i --follow-symlinks '0,/^password.*/s/^password.*/password    requisite                                    pam_pwquality.so\n&/' $FILE_PATH
38a2c0
+    fi
38a2c0
+fi
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml
38a2c0
new file mode 100644
38a2c0
index 00000000000..84f32456beb
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml
38a2c0
@@ -0,0 +1,21 @@
38a2c0
+<def-group>
38a2c0
+  <definition class="compliance" id="{{{ rule_id }}}" version="1">
38a2c0
+    {{{ oval_metadata("The PAM module pam_pwquality is used in password-auth") }}}
38a2c0
+    <criteria comment="Condition for pam_pwquality in password-auth is satisfied">
38a2c0
+      
38a2c0
+                 test_ref="test_accounts_password_pam_pwquality_password_auth"/>
38a2c0
+      </criteria>
38a2c0
+  </definition>
38a2c0
+
38a2c0
+  <ind:textfilecontent54_object id="object_accounts_password_pam_pwquality_password_auth" version="1">
38a2c0
+    <ind:filepath>/etc/pam.d/password-auth</ind:filepath>
38a2c0
+    <ind:pattern operation="pattern match">^password[\s]*requisite[\s]*pam_pwquality\.so</ind:pattern>
38a2c0
+    <ind:instance datatype="int" operation="equals">1</ind:instance>
38a2c0
+  </ind:textfilecontent54_object>
38a2c0
+
38a2c0
+  
38a2c0
+                              id="test_accounts_password_pam_pwquality_password_auth"
38a2c0
+                              comment="check the configuration of /etc/pam.d/password-auth">
38a2c0
+    <ind:object object_ref="object_accounts_password_pam_pwquality_password_auth"/>
38a2c0
+  </ind:textfilecontent54_test>
38a2c0
+</def-group>
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml
38a2c0
new file mode 100644
38a2c0
index 00000000000..6c7bb1ad7a0
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml
38a2c0
@@ -0,0 +1,35 @@
38a2c0
+documentation_complete: true
38a2c0
+
38a2c0
+prodtype: fedora,rhel7,rhel8,rhel9,rhv4
38a2c0
+
38a2c0
+title: 'Ensure PAM password complexity module is enabled in password-auth'
38a2c0
+
38a2c0
+description: |-
38a2c0
+    To enable PAM password complexity in password-auth file:
38a2c0
+    Edit the <tt>password</tt> section in
38a2c0
+    <tt>/etc/pam.d/password-auth</tt> to show
38a2c0
+    <tt>password    requisite                                    pam_pwquality.so</tt>.
38a2c0
+
38a2c0
+rationale: |-
38a2c0
+    Enabling PAM password complexity permits to enforce strong passwords and consequently
38a2c0
+    makes the system less prone to dictionary attacks.
38a2c0
+
38a2c0
+severity: medium
38a2c0
+
38a2c0
+identifiers:
38a2c0
+    cce@rhel7: CCE-85876-1
38a2c0
+    cce@rhel8: CCE-85877-9
38a2c0
+    cce@rhel9: CCE-85878-7
38a2c0
+
38a2c0
+references:
38a2c0
+    stigid@rhel8: RHEL-08-020100
38a2c0
+
38a2c0
+ocil_clause: 'pam_pwquality.so is not enabled in password-auth'
38a2c0
+
38a2c0
+ocil: |-
38a2c0
+    To check if pam_pwhistory.so is enabled in password-auth, run the following command:
38a2c0
+    
$ grep pam_pwquality /etc/pam.d/password-auth
38a2c0
+    The output should be similar to the following:
38a2c0
+    
password    requisite                                    pam_pwquality.so
38a2c0
+
38a2c0
+platform: pam
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..3d696c36b76
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh
38a2c0
@@ -0,0 +1,11 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth"
38a2c0
+sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $CUSTOM_SYSTEM_AUTH
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..0435899262b
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh
38a2c0
@@ -0,0 +1,13 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth"
38a2c0
+if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_SYSTEM_AUTH) -eq 0 ]; then
38a2c0
+    sed -i --follow-symlinks '0,/^password.*/s/^password.*/password     requisite   pam_pwquality.so\n&/' $CUSTOM_SYSTEM_AUTH
38a2c0
+fi
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..472616a51f6
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh
38a2c0
@@ -0,0 +1,11 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth"
38a2c0
+sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $CUSTOM_SYSTEM_AUTH
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..59f9d6f77c4
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh
38a2c0
@@ -0,0 +1,9 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+# remediation = none
38a2c0
+
38a2c0
+SYSTEM_AUTH_FILE="/etc/pam.d/password-auth"
38a2c0
+
38a2c0
+# This modification will break the integrity checks done by authselect.
38a2c0
+sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $SYSTEM_AUTH_FILE
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..71f87b19045
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh
38a2c0
@@ -0,0 +1,8 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = pam
38a2c0
+# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora
38a2c0
+
38a2c0
+config_file=/etc/pam.d/password-auth
38a2c0
+if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $config_file) -eq 0 ]; then
38a2c0
+    sed -i --follow-symlinks '0,/^password.*/s/^password.*/password		requisite	pam_pwquality.so\n&/' $config_file
38a2c0
+fi
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..95b73b24d26
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh
38a2c0
@@ -0,0 +1,7 @@
38a2c0
+#!/bin/bash
38a2c0
+# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora
38a2c0
+# packages = pam
38a2c0
+
38a2c0
+config_file=/etc/pam.d/password-auth
38a2c0
+
38a2c0
+sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $config_file
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml
38a2c0
new file mode 100644
38a2c0
index 00000000000..13cd20458ed
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml
38a2c0
@@ -0,0 +1,150 @@
38a2c0
+# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel
38a2c0
+# reboot = false
38a2c0
+# strategy = configure
38a2c0
+# complexity = low
38a2c0
+# disruption = medium
38a2c0
+
38a2c0
+- name: Check for existing pam_pwquality.so entry
38a2c0
+  ansible.builtin.lineinfile:
38a2c0
+    path: "/etc/pam.d/system-auth"
38a2c0
+    create: no
38a2c0
+    regexp: '^password.*pam_pwquality.so.*'
38a2c0
+    state: absent
38a2c0
+  check_mode: true
38a2c0
+  changed_when: false
38a2c0
+  register: result_pam_pwquality_present
38a2c0
+
38a2c0
+- name: Check if system relies on authselect
38a2c0
+  ansible.builtin.stat:
38a2c0
+    path: /usr/bin/authselect
38a2c0
+  register: result_authselect_present
38a2c0
+
38a2c0
+- name: "Remediation where authselect tool is present"
38a2c0
+  block:
38a2c0
+    - name: Check the integrity of the current authselect profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect check
38a2c0
+      register: result_authselect_check_cmd
38a2c0
+      changed_when: false
38a2c0
+      ignore_errors: true
38a2c0
+
38a2c0
+    - name: Informative message based on the authselect integrity check result
38a2c0
+      ansible.builtin.assert:
38a2c0
+        that:
38a2c0
+          - result_authselect_check_cmd is success
38a2c0
+        fail_msg:
38a2c0
+        - authselect integrity check failed. Remediation aborted!
38a2c0
+        - This remediation could not be applied because the authselect profile is not intact.
38a2c0
+        - It is not recommended to manually edit the PAM files when authselect is available.
38a2c0
+        - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended.
38a2c0
+        success_msg:
38a2c0
+        - authselect integrity check passed
38a2c0
+
38a2c0
+    - name: Get authselect current profile
38a2c0
+      ansible.builtin.shell:
38a2c0
+        cmd: authselect current -r | awk '{ print $1 }'
38a2c0
+      register: result_authselect_profile
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+
38a2c0
+    - name: Define the current authselect profile as a local fact
38a2c0
+      ansible.builtin.set_fact:
38a2c0
+        authselect_current_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+        authselect_custom_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_profile.stdout is match("custom/")
38a2c0
+
38a2c0
+    - name: Define the new authselect custom profile as a local fact
38a2c0
+      ansible.builtin.set_fact:
38a2c0
+        authselect_current_profile: "{{ result_authselect_profile.stdout }}"
38a2c0
+        authselect_custom_profile: "custom/hardening"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_profile.stdout is not match("custom/")
38a2c0
+
38a2c0
+    - name: Get authselect current features to also enable them in the custom profile
38a2c0
+      ansible.builtin.shell:
38a2c0
+        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
38a2c0
+      register: result_authselect_features
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+
38a2c0
+    - name: Check if any custom profile with the same name was already created in the past
38a2c0
+      ansible.builtin.stat:
38a2c0
+        path: /etc/authselect/{{ authselect_custom_profile }}
38a2c0
+      register: result_authselect_custom_profile_present
38a2c0
+      changed_when: false
38a2c0
+      when:
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+
38a2c0
+    - name: Create a custom profile based on the current profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect create-profile hardening -b sssd
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - not result_authselect_custom_profile_present.stat.exists
38a2c0
+
38a2c0
+    - name: Ensure the desired configuration is present in the custom profile
38a2c0
+      ansible.builtin.lineinfile:
38a2c0
+        dest: "/etc/authselect/{{ authselect_custom_profile }}/system-auth"
38a2c0
+        insertbefore: ^password.*sufficient.*pam_unix.so.*
38a2c0
+        line: "password    requisite                                    pam_pwquality.so"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_pam_pwquality_present.found == 0
38a2c0
+
38a2c0
+    - name: Ensure a backup of current authselect profile before selecting the custom profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect apply-changes -b --backup=before-pwquality-hardening.backup
38a2c0
+      register: result_authselect_backup
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - authselect_custom_profile is not match(authselect_current_profile)
38a2c0
+
38a2c0
+    - name: Ensure the custom profile is selected
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect select {{ authselect_custom_profile }} --force
38a2c0
+      register: result_pam_authselect_select_profile
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - authselect_current_profile is not match("custom/")
38a2c0
+        - authselect_custom_profile is not match(authselect_current_profile)
38a2c0
+
38a2c0
+    - name: Restore the authselect features in the custom profile
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect enable-feature {{ item }}
38a2c0
+      loop: "{{ result_authselect_features.stdout_lines }}"
38a2c0
+      when:
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+        - result_authselect_features is not skipped
38a2c0
+        - result_pam_authselect_select_profile is not skipped
38a2c0
+
38a2c0
+    - name: Ensure the custom profile changes are applied
38a2c0
+      ansible.builtin.command:
38a2c0
+        cmd: authselect apply-changes -b --backup=after-pwquality-hardening.backup
38a2c0
+      when:
38a2c0
+        - result_authselect_check_cmd is success
38a2c0
+        - result_authselect_profile is not skipped
38a2c0
+  when:
38a2c0
+  - result_authselect_present.stat.exists
38a2c0
+
38a2c0
+# For systems without authselect
38a2c0
+- name: "Remediation where authselect tool is not present and PAM files are directly edited"
38a2c0
+  block:
38a2c0
+    - name: Ensure the desired configuration is present in the custom profile
38a2c0
+      ansible.builtin.lineinfile:
38a2c0
+        dest: "/etc/pam.d/system-auth"
38a2c0
+        insertbefore: ^password.*sufficient.*pam_unix.so.*
38a2c0
+        line: "password    requisite                                    pam_pwquality.so"
38a2c0
+      when:
38a2c0
+        - result_pam_pwquality_present.found == 0
38a2c0
+  when:
38a2c0
+    - not result_authselect_present.stat.exists
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..9a7972a3f93
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh
38a2c0
@@ -0,0 +1,41 @@
38a2c0
+# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel
38a2c0
+
38a2c0
+PAM_FILE="system-auth"
38a2c0
+
38a2c0
+if [ -f /usr/bin/authselect ]; then
38a2c0
+    if authselect check; then
38a2c0
+        CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
38a2c0
+        # Standard profiles delivered with authselect should not be modified.
38a2c0
+        # If not already in use, a custom profile is created preserving the enabled features.
38a2c0
+        if [[ ! $CURRENT_PROFILE == custom/* ]]; then
38a2c0
+            ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
38a2c0
+            authselect create-profile hardening -b $CURRENT_PROFILE
38a2c0
+            CURRENT_PROFILE="custom/hardening"
38a2c0
+            # Ensure a backup before changing the profile
38a2c0
+            authselect apply-changes -b --backup=before-pwquality-hardening.backup
38a2c0
+            authselect select $CURRENT_PROFILE
38a2c0
+            for feature in $ENABLED_FEATURES; do
38a2c0
+                authselect enable-feature $feature;
38a2c0
+            done
38a2c0
+        fi
38a2c0
+        # Include the desired configuration in the custom profile
38a2c0
+        CUSTOM_FILE="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE"
38a2c0
+        # The line should be included on the top password section
38a2c0
+		if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_FILE) -eq 0 ]; then
38a2c0
+  		  sed -i --follow-symlinks '0,/^password.*/s/^password.*/password    requisite                                    pam_pwquality.so\n&/' $CUSTOM_FILE
38a2c0
+		fi
38a2c0
+        authselect apply-changes -b --backup=after-pwquality-hardening.backup
38a2c0
+    else
38a2c0
+        echo "
38a2c0
+authselect integrity check failed. Remediation aborted!
38a2c0
+This remediation could not be applied because the authselect profile is not intact.
38a2c0
+It is not recommended to manually edit the PAM files when authselect is available.
38a2c0
+In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
38a2c0
+        false
38a2c0
+    fi
38a2c0
+else
38a2c0
+    FILE_PATH="/etc/pam.d/$PAM_FILE"
38a2c0
+    if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $FILE_PATH) -eq 0 ]; then
38a2c0
+        sed -i --follow-symlinks '0,/^password.*/s/^password.*/password    requisite                                    pam_pwquality.so\n&/' $FILE_PATH
38a2c0
+    fi
38a2c0
+fi
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml
38a2c0
new file mode 100644
38a2c0
index 00000000000..f8d241f1ff2
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml
38a2c0
@@ -0,0 +1,21 @@
38a2c0
+<def-group>
38a2c0
+  <definition class="compliance" id="{{{ rule_id }}}" version="1">
38a2c0
+    {{{ oval_metadata("The PAM module pam_pwquality is used in system-auth") }}}
38a2c0
+    <criteria comment="Condition for pam_pwquality in system-auth is satisfied">
38a2c0
+      
38a2c0
+                 test_ref="test_accounts_password_pam_pwquality_system_auth"/>
38a2c0
+      </criteria>
38a2c0
+  </definition>
38a2c0
+
38a2c0
+  <ind:textfilecontent54_object id="object_accounts_password_pam_pwquality_system_auth" version="1">
38a2c0
+    <ind:filepath>/etc/pam.d/system-auth</ind:filepath>
38a2c0
+    <ind:pattern operation="pattern match">^password[\s]*requisite[\s]*pam_pwquality\.so</ind:pattern>
38a2c0
+    <ind:instance datatype="int" operation="equals">1</ind:instance>
38a2c0
+  </ind:textfilecontent54_object>
38a2c0
+
38a2c0
+  
38a2c0
+                              id="test_accounts_password_pam_pwquality_system_auth"
38a2c0
+                              comment="check the configuration of /etc/pam.d/system-auth">
38a2c0
+    <ind:object object_ref="object_accounts_password_pam_pwquality_system_auth"/>
38a2c0
+  </ind:textfilecontent54_test>
38a2c0
+</def-group>
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml
38a2c0
new file mode 100644
38a2c0
index 00000000000..ea42ff9b07a
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml
38a2c0
@@ -0,0 +1,35 @@
38a2c0
+documentation_complete: true
38a2c0
+
38a2c0
+prodtype: fedora,rhel7,rhel8,rhel9,rhv4
38a2c0
+
38a2c0
+title: 'Ensure PAM password complexity module is enabled in system-auth'
38a2c0
+
38a2c0
+description: |-
38a2c0
+    To enable PAM password complexity in system-auth file:
38a2c0
+    Edit the <tt>password</tt> section in
38a2c0
+    <tt>/etc/pam.d/system-auth</tt> to show
38a2c0
+    <tt>password    requisite                                    pam_pwquality.so</tt>.
38a2c0
+
38a2c0
+rationale: |-
38a2c0
+    Enabling PAM password complexity permits to enforce strong passwords and consequently
38a2c0
+    makes the system less prone to dictionary attacks.
38a2c0
+
38a2c0
+severity: medium
38a2c0
+
38a2c0
+identifiers:
38a2c0
+    cce@rhel7: CCE-85874-6
38a2c0
+    cce@rhel8: CCE-85872-0
38a2c0
+    cce@rhel9: CCE-85873-8
38a2c0
+
38a2c0
+references:
38a2c0
+    stigid@rhel8: RHEL-08-020101
38a2c0
+
38a2c0
+ocil_clause: 'pam_pwquality.so is not enabled in system-auth'
38a2c0
+
38a2c0
+ocil: |-
38a2c0
+    To check if pam_pwhistory.so is enabled in system-auth, run the following command:
38a2c0
+    
$ grep pam_pwquality /etc/pam.d/system-auth
38a2c0
+    The output should be similar to the following:
38a2c0
+    
password    requisite                                    pam_pwquality.so
38a2c0
+
38a2c0
+platform: pam
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..849f16d0f93
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh
38a2c0
@@ -0,0 +1,11 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth"
38a2c0
+sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $CUSTOM_SYSTEM_AUTH
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..6a98c244980
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh
38a2c0
@@ -0,0 +1,13 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth"
38a2c0
+if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_SYSTEM_AUTH) -eq 0 ]; then
38a2c0
+    sed -i --follow-symlinks '0,/^password.*/s/^password.*/password     requisite   pam_pwquality.so\n&/' $CUSTOM_SYSTEM_AUTH
38a2c0
+fi
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..6786f6c13d7
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh
38a2c0
@@ -0,0 +1,11 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+
38a2c0
+authselect create-profile hardening -b sssd
38a2c0
+CUSTOM_PROFILE="custom/hardening"
38a2c0
+authselect select $CUSTOM_PROFILE --force
38a2c0
+
38a2c0
+CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth"
38a2c0
+sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $CUSTOM_SYSTEM_AUTH
38a2c0
+authselect apply-changes -b
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..b3d9e5884f5
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh
38a2c0
@@ -0,0 +1,9 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = authselect
38a2c0
+# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
38a2c0
+# remediation = none
38a2c0
+
38a2c0
+SYSTEM_AUTH_FILE="/etc/pam.d/system-auth"
38a2c0
+
38a2c0
+# This modification will break the integrity checks done by authselect.
38a2c0
+sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $SYSTEM_AUTH_FILE
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..71f87b19045
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh
38a2c0
@@ -0,0 +1,8 @@
38a2c0
+#!/bin/bash
38a2c0
+# packages = pam
38a2c0
+# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora
38a2c0
+
38a2c0
+config_file=/etc/pam.d/password-auth
38a2c0
+if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $config_file) -eq 0 ]; then
38a2c0
+    sed -i --follow-symlinks '0,/^password.*/s/^password.*/password		requisite	pam_pwquality.so\n&/' $config_file
38a2c0
+fi
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh
38a2c0
new file mode 100644
38a2c0
index 00000000000..3c8f6f79fe9
38a2c0
--- /dev/null
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh
38a2c0
@@ -0,0 +1,7 @@
38a2c0
+#!/bin/bash
38a2c0
+# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora
38a2c0
+# packages = pam
38a2c0
+
38a2c0
+config_file=/etc/pam.d/system-auth
38a2c0
+
38a2c0
+sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $config_file
38a2c0
diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml
38a2c0
index eeb55a6ff5c..6b2219a3eab 100644
38a2c0
--- a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml
38a2c0
+++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml
38a2c0
@@ -6,13 +6,16 @@ title: 'Ensure PAM Enforces Password Requirements - Authentication Retry Prompts
38a2c0
 
38a2c0
 description: |-
38a2c0
     To configure the number of retry prompts that are permitted per-session:
38a2c0
+    {{% if product in ['rhel8', 'rhel9'] %}}
38a2c0
+    Edit the <tt>/etc/security/pwquality.conf</tt> to include
38a2c0
+    {{% else %}}
38a2c0
     Edit the <tt>pam_pwquality.so</tt> statement in
38a2c0
     {{% if 'ubuntu' not in product %}}
38a2c0
-    <tt>/etc/pam.d/system-auth</tt> {{% if product in ['rhel8', 'rhel9'] %}} and
38a2c0
-    <tt>/etc/pam.d/password-auth</tt> {{% endif %}} to show
38a2c0
+    <tt>/etc/pam.d/system-auth</tt> to show
38a2c0
     {{% else %}}
38a2c0
     <tt>/etc/pam.d/common-password</tt> to show
38a2c0
     {{% endif %}}
38a2c0
+    {{% endif %}}
38a2c0
     <tt>retry={{{xccdf_value("var_password_pam_retry") }}}</tt>, or a lower value if site
38a2c0
     policy is more restrictive. The DoD requirement is a maximum of 3 prompts
38a2c0
     per session.
38a2c0
@@ -48,17 +51,21 @@ references:
38a2c0
     stigid@ol7: OL07-00-010119
38a2c0
     stigid@ol8: OL08-00-020100
38a2c0
     stigid@rhel7: RHEL-07-010119
38a2c0
-    stigid@rhel8: RHEL-08-020100
38a2c0
+    stigid@rhel8: RHEL-08-020104
38a2c0
     stigid@ubuntu2004: UBTU-20-010057
38a2c0
 
38a2c0
 ocil_clause: 'it is not the required value'
38a2c0
 
38a2c0
 ocil: |-
38a2c0
     To check how many retry attempts are permitted on a per-session basis, run the following command:
38a2c0
+    {{% if product in ['rhel8', 'rhel9'] %}}
38a2c0
+    
$ grep retry /etc/security/pwquality.conf
38a2c0
+    {{% else %}}
38a2c0
     {{% if 'ubuntu' in product %}}
38a2c0
     
$ grep pam_pwquality /etc/pam.d/common-password
38a2c0
     {{% else %}}
38a2c0
-    
$ grep pam_pwquality /etc/pam.d/system-auth {{% if product in ['rhel8', 'rhel9'] %}}/etc/pam.d/password-auth{{% endif %}}
38a2c0
+    
$ grep pam_pwquality /etc/pam.d/system-auth
38a2c0
+    {{% endif %}}
38a2c0
     {{% endif %}}
38a2c0
     The <tt>retry</tt> parameter will indicate how many attempts are permitted.
38a2c0
     The DoD required value is less than or equal to 3.
38a2c0
diff --git a/products/rhel8/profiles/stig.profile b/products/rhel8/profiles/stig.profile
38a2c0
index d92bc72971c..62fc512f05e 100644
38a2c0
--- a/products/rhel8/profiles/stig.profile
38a2c0
+++ b/products/rhel8/profiles/stig.profile
38a2c0
@@ -523,6 +523,20 @@ selections:
38a2c0
     - sssd_enable_certmap
38a2c0
 
38a2c0
     # RHEL-08-020100
38a2c0
+    - accounts_password_pam_pwquality_password_auth
38a2c0
+
38a2c0
+    # RHEL-08-020101
38a2c0
+    - accounts_password_pam_pwquality_system_auth
38a2c0
+
38a2c0
+    # RHEL-08-020102
38a2c0
+    # This is only required for RHEL8 systems below version 8.4 where the
38a2c0
+    # retry parameter was not yet available on /etc/security/pwquality.conf.
38a2c0
+
38a2c0
+    # RHEL-08-020103
38a2c0
+    # This is only required for RHEL8 systems below version 8.4 where the
38a2c0
+    # retry parameter was not yet available on /etc/security/pwquality.conf.
38a2c0
+
38a2c0
+    # RHEL-08-020104
38a2c0
     - accounts_password_pam_retry
38a2c0
 
38a2c0
     # RHEL-08-020110
38a2c0
diff --git a/products/rhel9/profiles/stig.profile b/products/rhel9/profiles/stig.profile
38a2c0
index 42c6d0e9aca..ad08a6d3410 100644
38a2c0
--- a/products/rhel9/profiles/stig.profile
38a2c0
+++ b/products/rhel9/profiles/stig.profile
38a2c0
@@ -524,6 +524,20 @@ selections:
38a2c0
     - sssd_enable_certmap
38a2c0
 
38a2c0
     # RHEL-08-020100
38a2c0
+    - accounts_password_pam_pwquality_password_auth
38a2c0
+
38a2c0
+    # RHEL-08-020101
38a2c0
+    - accounts_password_pam_pwquality_system_auth
38a2c0
+
38a2c0
+    # RHEL-08-020102
38a2c0
+    # This is only required for RHEL8 systems below version 8.4 where the
38a2c0
+    # retry parameter was not yet available on /etc/security/pwquality.conf.
38a2c0
+
38a2c0
+    # RHEL-08-020103
38a2c0
+    # This is only required for RHEL8 systems below version 8.4 where the
38a2c0
+    # retry parameter was not yet available on /etc/security/pwquality.conf.
38a2c0
+
38a2c0
+    # RHEL-08-020104
38a2c0
     - accounts_password_pam_retry
38a2c0
 
38a2c0
     # RHEL-08-020110
38a2c0
diff --git a/tests/data/profile_stability/rhel8/stig.profile b/tests/data/profile_stability/rhel8/stig.profile
38a2c0
index e4fee44f9f9..33e82401c3d 100644
38a2c0
--- a/tests/data/profile_stability/rhel8/stig.profile
38a2c0
+++ b/tests/data/profile_stability/rhel8/stig.profile
38a2c0
@@ -53,6 +53,8 @@ selections:
38a2c0
 - accounts_password_pam_ocredit
38a2c0
 - accounts_password_pam_pwhistory_remember_password_auth
38a2c0
 - accounts_password_pam_pwhistory_remember_system_auth
38a2c0
+- accounts_password_pam_pwquality_password_auth
38a2c0
+- accounts_password_pam_pwquality_system_auth
38a2c0
 - accounts_password_pam_retry
38a2c0
 - accounts_password_pam_ucredit
38a2c0
 - accounts_password_pam_unix_rounds_password_auth
38a2c0
diff --git a/tests/data/profile_stability/rhel8/stig_gui.profile b/tests/data/profile_stability/rhel8/stig_gui.profile
38a2c0
index 83d04775e3a..5beeb4f28af 100644
38a2c0
--- a/tests/data/profile_stability/rhel8/stig_gui.profile
38a2c0
+++ b/tests/data/profile_stability/rhel8/stig_gui.profile
38a2c0
@@ -64,6 +64,8 @@ selections:
38a2c0
 - accounts_password_pam_ocredit
38a2c0
 - accounts_password_pam_pwhistory_remember_password_auth
38a2c0
 - accounts_password_pam_pwhistory_remember_system_auth
38a2c0
+- accounts_password_pam_pwquality_password_auth
38a2c0
+- accounts_password_pam_pwquality_system_auth
38a2c0
 - accounts_password_pam_retry
38a2c0
 - accounts_password_pam_ucredit
38a2c0
 - accounts_password_pam_unix_rounds_password_auth