- GRAYBYTE UNDETECTABLE CODES -

403Webshell
Server IP : 184.154.167.98  /  Your IP : 3.129.63.214
Web Server : Apache
System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64
User : puertode ( 1767)
PHP Version : 8.2.26
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/scap-security-guide/ansible/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/scap-security-guide/ansible/almalinux8-playbook-stig.yml
---
###############################################################################
#
# Ansible Playbook for DISA STIG for Red Hat Enterprise Linux 8
#
# Profile Description:
# This profile contains configuration checks that align to the
# DISA STIG for Red Hat Enterprise Linux 8 V2R1.
# In addition to being applicable to Red Hat Enterprise Linux 8, DISA recognizes this
# configuration baseline as applicable to the operating system tier of
# Red Hat technologies that are based on Red Hat Enterprise Linux 8, such as:
# - Red Hat Enterprise Linux Server
# - Red Hat Enterprise Linux Workstation and Desktop
# - Red Hat Enterprise Linux for HPC
# - Red Hat Storage
# - Red Hat Containers with a Red Hat Enterprise Linux 8 image
#
# Profile ID:  xccdf_org.ssgproject.content_profile_stig
# Benchmark ID:  xccdf_org.ssgproject.content_benchmark_ALMALINUX-8
# Benchmark Version:  0.1.75
# XCCDF Version:  1.2
#
# This file can be generated by OpenSCAP using:
# $ oscap xccdf generate fix --profile xccdf_org.ssgproject.content_profile_stig --fix-type ansible ssg-almalinux8-ds.xml
#
# This Ansible Playbook is generated from an XCCDF profile without preliminary evaluation.
# It attempts to fix every selected rule, even if the system is already compliant.
#
# How to apply this Ansible Playbook:
# $ ansible-playbook -i "localhost," -c local playbook.yml
# $ ansible-playbook -i "192.168.1.155," playbook.yml
# $ ansible-playbook -i inventory.ini playbook.yml
#
###############################################################################


- name: Ansible Playbook for xccdf_org.ssgproject.content_profile_stig
  hosts: all
  vars:
    var_aide_scan_notification_email: !!str root@localhost
    var_system_crypto_policy: !!str FIPS
    sshd_approved_ciphers: !!str aes256-ctr,aes192-ctr,aes128-ctr,aes256-gcm@openssh.com,aes128-gcm@openssh.com
    sshd_approved_macs: !!str hmac-sha2-512,hmac-sha2-256,hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
    inactivity_timeout_value: !!str 900
    var_screensaver_lock_delay: !!str 5
    var_sudo_timestamp_timeout: !!str 0
    var_authselect_profile: !!str sssd
    login_banner_text: !!str ^(You[\s\n]+are[\s\n]+accessing[\s\n]+a[\s\n]+U\.S\.[\s\n]+Government[\s\n]+\(USG\)[\s\n]+Information[\s\n]+System[\s\n]+\(IS\)[\s\n]+that[\s\n]+is[\s\n]+provided[\s\n]+for[\s\n]+USG\-authorized[\s\n]+use[\s\n]+only\.[\s\n]+By[\s\n]+using[\s\n]+this[\s\n]+IS[\s\n]+\(which[\s\n]+includes[\s\n]+any[\s\n]+device[\s\n]+attached[\s\n]+to[\s\n]+this[\s\n]+IS\),[\s\n]+you[\s\n]+consent[\s\n]+to[\s\n]+the[\s\n]+following[\s\n]+conditions\:(?:[\n]+|(?:\\n)+)\-The[\s\n]+USG[\s\n]+routinely[\s\n]+intercepts[\s\n]+and[\s\n]+monitors[\s\n]+communications[\s\n]+on[\s\n]+this[\s\n]+IS[\s\n]+for[\s\n]+purposes[\s\n]+including,[\s\n]+but[\s\n]+not[\s\n]+limited[\s\n]+to,[\s\n]+penetration[\s\n]+testing,[\s\n]+COMSEC[\s\n]+monitoring,[\s\n]+network[\s\n]+operations[\s\n]+and[\s\n]+defense,[\s\n]+personnel[\s\n]+misconduct[\s\n]+\(PM\),[\s\n]+law[\s\n]+enforcement[\s\n]+\(LE\),[\s\n]+and[\s\n]+counterintelligence[\s\n]+\(CI\)[\s\n]+investigations\.(?:[\n]+|(?:\\n)+)\-At[\s\n]+any[\s\n]+time,[\s\n]+the[\s\n]+USG[\s\n]+may[\s\n]+inspect[\s\n]+and[\s\n]+seize[\s\n]+data[\s\n]+stored[\s\n]+on[\s\n]+this[\s\n]+IS\.(?:[\n]+|(?:\\n)+)\-Communications[\s\n]+using,[\s\n]+or[\s\n]+data[\s\n]+stored[\s\n]+on,[\s\n]+this[\s\n]+IS[\s\n]+are[\s\n]+not[\s\n]+private,[\s\n]+are[\s\n]+subject[\s\n]+to[\s\n]+routine[\s\n]+monitoring,[\s\n]+interception,[\s\n]+and[\s\n]+search,[\s\n]+and[\s\n]+may[\s\n]+be[\s\n]+disclosed[\s\n]+or[\s\n]+used[\s\n]+for[\s\n]+any[\s\n]+USG\-authorized[\s\n]+purpose\.(?:[\n]+|(?:\\n)+)\-This[\s\n]+IS[\s\n]+includes[\s\n]+security[\s\n]+measures[\s\n]+\(e\.g\.,[\s\n]+authentication[\s\n]+and[\s\n]+access[\s\n]+controls\)[\s\n]+to[\s\n]+protect[\s\n]+USG[\s\n]+interests\-\-not[\s\n]+for[\s\n]+your[\s\n]+personal[\s\n]+benefit[\s\n]+or[\s\n]+privacy\.(?:[\n]+|(?:\\n)+)\-Notwithstanding[\s\n]+the[\s\n]+above,[\s\n]+using[\s\n]+this[\s\n]+IS[\s\n]+does[\s\n]+not[\s\n]+constitute[\s\n]+consent[\s\n]+to[\s\n]+PM,[\s\n]+LE[\s\n]+or[\s\n]+CI[\s\n]+investigative[\s\n]+searching[\s\n]+or[\s\n]+monitoring[\s\n]+of[\s\n]+the[\s\n]+content[\s\n]+of[\s\n]+privileged[\s\n]+communications,[\s\n]+or[\s\n]+work[\s\n]+product,[\s\n]+related[\s\n]+to[\s\n]+personal[\s\n]+representation[\s\n]+or[\s\n]+services[\s\n]+by[\s\n]+attorneys,[\s\n]+psychotherapists,[\s\n]+or[\s\n]+clergy,[\s\n]+and[\s\n]+their[\s\n]+assistants\.[\s\n]+Such[\s\n]+communications[\s\n]+and[\s\n]+work[\s\n]+product[\s\n]+are[\s\n]+private[\s\n]+and[\s\n]+confidential\.[\s\n]+See[\s\n]+User[\s\n]+Agreement[\s\n]+for[\s\n]+details\.|I've[\s\n]+read[\s\n]+\&[\s\n]+consent[\s\n]+to[\s\n]+terms[\s\n]+in[\s\n]+IS[\s\n]+user[\s\n]+agreem't\.)$
    var_password_pam_remember: !!str 5
    var_password_pam_remember_control_flag: !!str requisite,required
    var_accounts_passwords_pam_faillock_deny: !!str 3
    var_accounts_passwords_pam_faillock_dir: !!str /var/log/faillock
    var_accounts_passwords_pam_faillock_fail_interval: !!str 900
    var_accounts_passwords_pam_faillock_unlock_time: !!str 0
    var_password_pam_dcredit: !!str -1
    var_password_pam_dictcheck: !!str 1
    var_password_pam_difok: !!str 8
    var_password_pam_lcredit: !!str -1
    var_password_pam_maxclassrepeat: !!str 4
    var_password_pam_maxrepeat: !!str 3
    var_password_pam_minclass: !!str 4
    var_password_pam_minlen: !!str 15
    var_password_pam_ocredit: !!str -1
    var_password_pam_retry: !!str 3
    var_password_pam_ucredit: !!str -1
    var_password_hashing_algorithm: !!str SHA512
    var_password_hashing_algorithm_pam: !!str sha512
    var_logind_session_timeout: !!str 600
    var_account_disable_post_pw_expiration: !!str 35
    var_accounts_maximum_age_login_defs: !!str 60
    var_accounts_minimum_age_login_defs: !!str 1
    var_accounts_password_minlen_login_defs: !!str 15
    var_accounts_fail_delay: !!str 4
    var_accounts_max_concurrent_login_sessions: !!str 10
    var_user_initialization_files_regex: !!str ^\.[\w\- ]+$
    var_accounts_user_umask: !!str 077
    rsyslog_remote_loghost_address: !!str logcollector
    sysctl_net_ipv6_conf_all_accept_ra_value: !!str 0
    sysctl_net_ipv6_conf_all_accept_redirects_value: !!str 0
    sysctl_net_ipv6_conf_all_accept_source_route_value: !!str 0
    sysctl_net_ipv6_conf_all_forwarding_value: !!str 0
    sysctl_net_ipv6_conf_default_accept_ra_value: !!str 0
    sysctl_net_ipv6_conf_default_accept_redirects_value: !!str 0
    sysctl_net_ipv6_conf_default_accept_source_route_value: !!str 0
    sysctl_net_ipv4_conf_all_accept_redirects_value: !!str 0
    sysctl_net_ipv4_conf_all_accept_source_route_value: !!str 0
    sysctl_net_ipv4_conf_all_forwarding_value: !!str 0
    sysctl_net_ipv4_conf_all_rp_filter_value: !!str 1
    sysctl_net_ipv4_conf_default_accept_redirects_value: !!str 0
    sysctl_net_ipv4_conf_default_accept_source_route_value: !!str 0
    sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value: !!str 1
    var_removable_partition: !!str /dev/cdrom
    sysctl_kernel_kptr_restrict_value: !!str 1
    var_slub_debug_options: !!str P
    var_selinux_policy_name: !!str targeted
    var_selinux_state: !!str enforcing
    var_multiple_time_servers: !!str 0.us.pool.ntp.mil
    var_time_service_set_maxpoll: !!str 16
    var_tftpd_secure_directory: !!str /var/lib/tftpboot
    var_sshd_set_keepalive: !!str 1
    sshd_idle_timeout_value: !!str 600
    var_rekey_limit_size: !!str 1G
    var_rekey_limit_time: !!str 1h
    var_sssd_certificate_verification_digest_function: !!str sha1
    var_auditd_disk_error_action: !!str syslog|single|halt
    var_auditd_disk_full_action: !!str syslog|single|halt
    var_auditd_action_mail_acct: !!str root
    var_auditd_space_left_action: !!str email
    var_auditd_space_left_percentage: !!str 25
    var_auditd_name_format: !!str hostname|fqd|numeric
  tasks:
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_aide_installed

    - name: Ensure aide is installed
      package:
        name: aide
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_aide_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_build_database
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Build and Test AIDE Database - Ensure AIDE Is Installed
      ansible.builtin.package:
        name: '{{ item }}'
        state: present
      with_items:
      - aide
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_build_database
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Build and Test AIDE Database - Build and Test AIDE Database
      ansible.builtin.command: /usr/sbin/aide --init
      changed_when: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_build_database
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Build and Test AIDE Database - Check Whether the Stock AIDE Database Exists
      ansible.builtin.stat:
        path: /var/lib/aide/aide.db.new.gz
      register: aide_database_stat
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_build_database
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Build and Test AIDE Database - Stage AIDE Database
      ansible.builtin.copy:
        src: /var/lib/aide/aide.db.new.gz
        dest: /var/lib/aide/aide.db.gz
        backup: true
        remote_src: true
      when:
      - '"kernel" in ansible_facts.packages'
      - (aide_database_stat.stat.exists is defined and aide_database_stat.stat.exists)
      tags:
      - CJIS-5.10.1.3
      - DISA-STIG-RHEL-08-010359
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_build_database
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure AIDE to Verify the Audit Tools - Gather List of Packages
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      ansible.builtin.package_facts:
        manager: auto
      when: '"kernel" in ansible_facts.packages'

    - name: Ensure aide is installed
      package:
        name: '{{ item }}'
        state: present
      with_items:
      - aide
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set audit_tools fact
      set_fact:
        audit_tools:
        - /usr/sbin/auditctl
        - /usr/sbin/auditd
        - /usr/sbin/augenrules
        - /usr/sbin/aureport
        - /usr/sbin/ausearch
        - /usr/sbin/autrace
        - /usr/sbin/rsyslogd
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure existing AIDE configuration for audit tools are correct
      lineinfile:
        path: /etc/aide.conf
        regexp: ^{{ item }}\s
        line: '{{ item }} p+i+n+u+g+s+b+acl+selinux+xattrs+sha512'
      with_items: '{{ audit_tools }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure AIDE to properly protect audit tools
      lineinfile:
        path: /etc/aide.conf
        line: '{{ item }} p+i+n+u+g+s+b+acl+selinux+xattrs+sha512'
      with_items: '{{ audit_tools }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030650
      - NIST-800-53-AU-9(3)
      - NIST-800-53-AU-9(3).1
      - aide_check_audit_tools
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010360
      - NIST-800-53-CM-3(5)
      - NIST-800-53-CM-6(a)
      - aide_scan_notification
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure AIDE is installed
      package:
        name: '{{ item }}'
        state: present
      with_items:
      - aide
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010360
      - NIST-800-53-CM-3(5)
      - NIST-800-53-CM-6(a)
      - aide_scan_notification
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Notification of Post-AIDE Scan Details
      cron:
        name: run AIDE check
        minute: 5
        hour: 4
        weekday: 0
        user: root
        job: /usr/sbin/aide  --check | /bin/mail -s "$(hostname) - AIDE Integrity Check"
          {{ var_aide_scan_notification_email }}
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010360
      - NIST-800-53-CM-3(5)
      - NIST-800-53-CM-6(a)
      - aide_scan_notification
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather list of packages
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040310
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_acls
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Get rules groups
      shell: |
        set -o pipefail
        LC_ALL=C grep "^[A-Z][A-Za-z_]*" /etc/aide.conf | grep -v "^ALLXTRAHASHES" | cut -f1 -d '=' | tr -d ' ' | sort -u || true
      when:
      - '"kernel" in ansible_facts.packages'
      - '''aide'' in ansible_facts.packages'
      register: find_rules_groups_results
      tags:
      - DISA-STIG-RHEL-08-040310
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_acls
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the acl rule is present when aide is installed.
      replace:
        path: /etc/aide.conf
        regexp: (^\s*{{ item }}\s*=\s*)(?!.*acl)([^\s]*)
        replace: \g<1>\g<2>+acl
      when:
      - '"kernel" in ansible_facts.packages'
      - find_rules_groups_results is not skipped and "'aide' in ansible_facts.packages"
      with_items: '{{ find_rules_groups_results.stdout_lines | map(''trim'') | list }}'
      tags:
      - DISA-STIG-RHEL-08-040310
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_acls
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather list of packages
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040300
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_ext_attributes
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Get rules groups
      shell: |
        set -o pipefail
        LC_ALL=C grep "^[A-Z][A-Za-z_]*" /etc/aide.conf | grep -v "^ALLXTRAHASHES" | cut -f1 -d '=' | tr -d ' ' | sort -u || true
      when:
      - '"kernel" in ansible_facts.packages'
      - '''aide'' in ansible_facts.packages'
      register: find_rules_groups_results
      tags:
      - DISA-STIG-RHEL-08-040300
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_ext_attributes
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the xattrs rule is present when aide is installed.
      replace:
        path: /etc/aide.conf
        regexp: (^\s*{{ item }}\s*=\s*)(?!.*xattrs)([^\s]*)
        replace: \g<1>\g<2>+xattrs
      when:
      - '"kernel" in ansible_facts.packages'
      - find_rules_groups_results is not skipped and "'aide' in ansible_facts.packages"
      with_items: '{{ find_rules_groups_results.stdout_lines | map(''trim'') | list }}'
      tags:
      - DISA-STIG-RHEL-08-040300
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - aide_verify_ext_attributes
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditctl
      stat:
        path: /sbin/auditctl
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/auditctl
      file:
        path: /sbin/auditctl
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/aureport
      stat:
        path: /sbin/aureport
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/aureport
      file:
        path: /sbin/aureport
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/ausearch
      stat:
        path: /sbin/ausearch
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/ausearch
      file:
        path: /sbin/ausearch
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/autrace
      stat:
        path: /sbin/autrace
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/autrace
      file:
        path: /sbin/autrace
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditd
      stat:
        path: /sbin/auditd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/auditd
      file:
        path: /sbin/auditd
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/rsyslogd
      stat:
        path: /sbin/rsyslogd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/rsyslogd
      file:
        path: /sbin/rsyslogd
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/augenrules
      stat:
        path: /sbin/augenrules
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /sbin/augenrules
      file:
        path: /sbin/augenrules
        group: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030640
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_group_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditctl
      stat:
        path: /sbin/auditctl
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/auditctl
      file:
        path: /sbin/auditctl
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/aureport
      stat:
        path: /sbin/aureport
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/aureport
      file:
        path: /sbin/aureport
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/ausearch
      stat:
        path: /sbin/ausearch
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/ausearch
      file:
        path: /sbin/ausearch
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/autrace
      stat:
        path: /sbin/autrace
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/autrace
      file:
        path: /sbin/autrace
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditd
      stat:
        path: /sbin/auditd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/auditd
      file:
        path: /sbin/auditd
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/rsyslogd
      stat:
        path: /sbin/rsyslogd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/rsyslogd
      file:
        path: /sbin/rsyslogd
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/augenrules
      stat:
        path: /sbin/augenrules
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /sbin/augenrules
      file:
        path: /sbin/augenrules
        owner: '0'
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030630
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_ownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditctl
      stat:
        path: /sbin/auditctl
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditctl
      file:
        path: /sbin/auditctl
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/aureport
      stat:
        path: /sbin/aureport
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/aureport
      file:
        path: /sbin/aureport
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/ausearch
      stat:
        path: /sbin/ausearch
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/ausearch
      file:
        path: /sbin/ausearch
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/autrace
      stat:
        path: /sbin/autrace
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/autrace
      file:
        path: /sbin/autrace
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/auditd
      stat:
        path: /sbin/auditd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditd
      file:
        path: /sbin/auditd
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/rsyslogd
      stat:
        path: /sbin/rsyslogd
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/rsyslogd
      file:
        path: /sbin/rsyslogd
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Test for existence /sbin/augenrules
      stat:
        path: /sbin/augenrules
      register: file_exists
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-s,g-ws,o-wt on /sbin/augenrules
      file:
        path: /sbin/augenrules
        mode: u-s,g-ws,o-wt
      when:
      - '"kernel" in ansible_facts.packages'
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030620
      - NIST-800-53-AU-9
      - configure_strategy
      - file_audit_tools_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_dracut_fips_module
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Check to see the current status of FIPS mode
      command: /usr/bin/fips-mode-setup --check
      register: is_fips_enabled
      changed_when: false
      failed_when: false
      when: ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_dracut_fips_module
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Enable FIPS mode
      command: /usr/bin/fips-mode-setup --enable
      when:
      - ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      - is_fips_enabled.stdout.find('FIPS mode is enabled.') == -1
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_dracut_fips_module
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Enable Dracut FIPS Module
      lineinfile:
        path: /etc/dracut.conf.d/40-fips.conf
        line: add_dracutmodules+=" fips "
      when: ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_dracut_fips_module
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-3(6)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_fips_mode
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy


    - name: Enable FIPS Mode - Check to See the Current Status of FIPS Mode
      ansible.builtin.command: /usr/bin/fips-mode-setup --check
      register: is_fips_enabled
      failed_when: false
      changed_when: false
      when: ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-3(6)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_fips_mode
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Enable FIPS Mode - Enable FIPS Mode
      ansible.builtin.command: /usr/bin/fips-mode-setup --enable
      when:
      - ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      - is_fips_enabled.stdout.find('FIPS mode is enabled.') == -1
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-3(6)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_fips_mode
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Enable FIPS Mode - Configure Crypto Policy
      ansible.builtin.lineinfile:
        path: /etc/crypto-policies/config
        regexp: ^(?!#)(\S+)$
        line: '{{ var_system_crypto_policy }}'
        create: true
      when: ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-3(6)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_fips_mode
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy

    - name: Enable FIPS Mode - Verify that Crypto Policy is Set (runtime)
      ansible.builtin.command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy
        }}
      when: ( not ( lookup("env", "container") == "bwrap-osbuild" ) and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-3(6)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-7
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - enable_fips_mode
      - high_severity
      - medium_complexity
      - medium_disruption
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - configure_bind_crypto_policy
      - configure_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed

    - name: Configure BIND to use System Crypto Policy - Check BIND configuration file
        exists
      ansible.builtin.stat:
        path: /etc/named.conf
      register: bind_config_file
      when: '"bind" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - configure_bind_crypto_policy
      - configure_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed

    - name: Configure BIND to use System Crypto Policy - Aborting remediation, file not
        found
      ansible.builtin.debug:
        msg: Aborting remediation as '/etc/named.conf' was not found.
      when:
      - '"bind" in ansible_facts.packages'
      - not bind_config_file.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - configure_bind_crypto_policy
      - configure_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed

    - name: Configure BIND to use System Crypto Policy - Insert crypto-policy into BIND
        config
      ansible.builtin.lineinfile:
        path: /etc/named.conf
        insertafter: ^\s*options\s*{
        line: ' include "/etc/crypto-policies/back-ends/bind.config";'
        state: present
      when:
      - '"bind" in ansible_facts.packages'
      - bind_config_file.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - configure_bind_crypto_policy
      - configure_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed


    - name: Configure System Cryptography Policy
      lineinfile:
        path: /etc/crypto-policies/config
        regexp: ^(?!#)(\S+)$
        line: '{{ var_system_crypto_policy }}'
        create: true
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.7
      - configure_crypto_policy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that Crypto Policy is Set (runtime)
      command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy }}
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.7
      - configure_crypto_policy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy


    - name: 'Configure GnuTLS library to use DoD-approved TLS Encryption: set_fact'
      set_fact:
        path: /etc/crypto-policies/back-ends/gnutls.config
        correct_value: +VERS-ALL:-VERS-DTLS0.9:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS1.0
        lineinfile_reg: \+VERS-ALL:-VERS-DTLS0\.9:-VERS-SSL3\.0:-VERS-TLS1\.0:-VERS-TLS1\.1:-VERS-DTLS1\.0
      tags:
      - DISA-STIG-RHEL-08-010295
      - NIST-800-53-AC-17(2)
      - configure_gnutls_tls_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure GnuTLS library to use DoD-approved TLS Encryption: stat'
      stat:
        path: '{{ path }}'
        follow: true
      register: gnutls_file
      tags:
      - DISA-STIG-RHEL-08-010295
      - NIST-800-53-AC-17(2)
      - configure_gnutls_tls_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure GnuTLS library to use DoD-approved TLS Encryption: Add'
      lineinfile:
        path: '{{ path }}'
        regexp: '{{ lineinfile_reg }}'
        line: '{{ correct_value }}'
        create: true
      when: not gnutls_file.stat.exists or gnutls_file.stat.size <= correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010295
      - NIST-800-53-AC-17(2)
      - configure_gnutls_tls_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Configure GnuTLS library to use DoD-approved TLS Encryption
      block:

      - name: 'Configure GnuTLS library to use DoD-approved TLS Encryption: Existing value
          check'
        lineinfile:
          path: '{{ path }}'
          create: false
          regexp: '{{ lineinfile_reg }}'
          state: absent
        check_mode: true
        changed_when: false
        register: gnutls

      - name: 'Configure GnuTLS library to use DoD-approved TLS Encryption: Update'
        replace:
          path: '{{ path }}'
          regexp: (\+VERS-ALL(?::-VERS-[A-Z]+\d\.\d)+)
          replace: '{{ correct_value }}'
        when: gnutls.found is defined and gnutls.found != 1
      when: gnutls_file.stat.exists and gnutls_file.stat.size > correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010295
      - NIST-800-53-AC-17(2)
      - configure_gnutls_tls_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Configure Kerberos to use System Crypto Policy
      file:
        src: /etc/crypto-policies/back-ends/krb5.config
        path: /etc/krb5.conf.d/crypto-policies
        state: link
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - configure_kerberos_crypto_policy
      - configure_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - reboot_required


    - name: Configure Libreswan to use System Crypto Policy
      lineinfile:
        path: /etc/ipsec.conf
        line: include /etc/crypto-policies/back-ends/libreswan.config
        create: true
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - configure_libreswan_crypto_policy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy


    - name: Configure OpenSSL library to use System Crypto Policy - Search for crypto_policy
        Section
      ansible.builtin.find:
        paths: /etc/pki/tls
        patterns: openssl.cnf
        contains: ^\s*\[\s*crypto_policy\s*]
      register: test_crypto_policy_group
      tags:
      - DISA-STIG-RHEL-08-010293
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - configure_openssl_crypto_policy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Configure OpenSSL library to use System Crypto Policy - Search for crypto_policy
        Section Together With .include Directive
      ansible.builtin.find:
        paths: /etc/pki/tls
        patterns: openssl.cnf
        contains: ^\s*\.include\s*(?:=\s*)?/etc/crypto-policies/back-ends/opensslcnf.config$
      register: test_crypto_policy_include_directive
      tags:
      - DISA-STIG-RHEL-08-010293
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - configure_openssl_crypto_policy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Configure OpenSSL library to use System Crypto Policy - Add .include Line
        for opensslcnf.config File in crypto_policy Section
      ansible.builtin.lineinfile:
        create: true
        insertafter: ^\s*\[\s*crypto_policy\s*]\s*
        line: .include /etc/crypto-policies/back-ends/opensslcnf.config
        path: /etc/pki/tls/openssl.cnf
      when:
      - test_crypto_policy_group.matched > 0
      - test_crypto_policy_include_directive.matched == 0
      tags:
      - DISA-STIG-RHEL-08-010293
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - configure_openssl_crypto_policy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Configure OpenSSL library to use System Crypto Policy - Add crypto_policy
        Section With .include for opensslcnf.config File
      ansible.builtin.lineinfile:
        create: true
        line: |-
          [crypto_policy]
          .include /etc/crypto-policies/back-ends/opensslcnf.config
        path: /etc/pki/tls/openssl.cnf
      when: test_crypto_policy_group.matched == 0
      tags:
      - DISA-STIG-RHEL-08-010293
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-12(2)
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - configure_openssl_crypto_policy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Configure SSH to use System Crypto Policy
      lineinfile:
        dest: /etc/sysconfig/sshd
        state: absent
        regexp: (?i)^\s*CRYPTO_POLICY.*$
      tags:
      - DISA-STIG-RHEL-08-010287
      - NIST-800-53-AC-17(2)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(6)
      - NIST-800-53-SC-13
      - PCI-DSS-Req-2.2
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.7
      - configure_ssh_crypto_policy
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: 'Configure SSH Daemon to Use FIPS 140-2 Validated Ciphers: openssh.config'
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*Ciphers\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/crypto-policies/back-ends/openssh.config
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*Ciphers\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/crypto-policies/back-ends/openssh.config
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*Ciphers\s+
          line: Ciphers {{ sshd_approved_ciphers }}
          state: present
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-AC-17(2)
      - harden_sshd_ciphers_openssh_conf_crypto_policy
      - high_severity
      - low_complexity
      - low_disruption
      - reboot_required
      - restrict_strategy


    - name: 'Configure SSH Server to Use FIPS 140-2 Validated Ciphers: opensshserver.config:
        Set facts'
      set_fact:
        path: /etc/crypto-policies/back-ends/opensshserver.config
        correct_value: -oCiphers={{ sshd_approved_ciphers }}
      tags:
      - DISA-STIG-RHEL-08-010291
      - NIST-800-53-AC-17(2)
      - harden_sshd_ciphers_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated Ciphers: opensshserver.config:
        Stat'
      stat:
        path: '{{ path }}'
        follow: true
      register: opensshserver_file
      tags:
      - DISA-STIG-RHEL-08-010291
      - NIST-800-53-AC-17(2)
      - harden_sshd_ciphers_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated Ciphers: opensshserver.config:
        Create'
      lineinfile:
        path: '{{ path }}'
        line: CRYPTO_POLICY='{{ correct_value }}'
        create: true
      when: not opensshserver_file.stat.exists or opensshserver_file.stat.size <= correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010291
      - NIST-800-53-AC-17(2)
      - harden_sshd_ciphers_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated Ciphers: opensshserver.config'
      block:

      - name: Existing value check
        lineinfile:
          path: '{{ path }}'
          create: false
          regexp: '{{ correct_value }}'
          state: absent
        check_mode: true
        changed_when: false
        register: opensshserver

      - name: Update/Correct value
        replace:
          path: '{{ path }}'
          regexp: (-oCiphers=\S+)
          replace: '{{ correct_value }}'
        when: opensshserver.found is defined and opensshserver.found != 1
      when: opensshserver_file.stat.exists and opensshserver_file.stat.size > correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010291
      - NIST-800-53-AC-17(2)
      - harden_sshd_ciphers_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: 'Configure SSH Daemon to Use FIPS 140-2 Validated MACs: openssh.config'
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*MACs\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/crypto-policies/back-ends/openssh.config
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*MACs\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/crypto-policies/back-ends/openssh.config
        lineinfile:
          path: /etc/crypto-policies/back-ends/openssh.config
          create: true
          regexp: (?i)^.*MACs\s+
          line: MACs {{ sshd_approved_macs }}
          state: present
      tags:
      - DISA-STIG-RHEL-08-010020
      - NIST-800-53-AC-17(2)
      - harden_sshd_macs_openssh_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: 'Configure SSH Server to Use FIPS 140-2 Validated MACs: opensshserver.config:
        Set facts'
      set_fact:
        path: /etc/crypto-policies/back-ends/opensshserver.config
        correct_value: -oMACs={{ sshd_approved_macs }}
      tags:
      - DISA-STIG-RHEL-08-010290
      - NIST-800-53-AC-17(2)
      - harden_sshd_macs_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated MACs: opensshserver.config:
        Stat'
      stat:
        path: '{{ path }}'
        follow: true
      register: opensshserver_file
      tags:
      - DISA-STIG-RHEL-08-010290
      - NIST-800-53-AC-17(2)
      - harden_sshd_macs_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated MACs: opensshserver.config:
        Create'
      lineinfile:
        path: '{{ path }}'
        line: CRYPTO_POLICY='{{ correct_value }}'
        create: true
      when: not opensshserver_file.stat.exists or opensshserver_file.stat.size <= correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010290
      - NIST-800-53-AC-17(2)
      - harden_sshd_macs_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: 'Configure SSH Server to Use FIPS 140-2 Validated MACs: opensshserver.config'
      block:

      - name: Existing value check
        lineinfile:
          path: '{{ path }}'
          create: false
          regexp: '{{ correct_value }}'
          state: absent
        check_mode: true
        changed_when: false
        register: opensshserver

      - name: Update/Correct value
        replace:
          path: '{{ path }}'
          regexp: (-oMACs=\S+)
          replace: '{{ correct_value }}'
        when: opensshserver.found is defined and opensshserver.found != 1
      when: opensshserver_file.stat.exists and opensshserver_file.stat.size > correct_value|length
      tags:
      - DISA-STIG-RHEL-08-010290
      - NIST-800-53-AC-17(2)
      - harden_sshd_macs_opensshserver_conf_crypto_policy
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020032
      - NIST-800-53-AC-23
      - NIST-800-53-CM-6(a)
      - dconf_gnome_disable_user_list
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Disable the GNOME3 Login User List
      ini_file:
        dest: /etc/dconf/db/gdm.d/00-security-settings
        section: org/gnome/login-screen
        option: disable-user-list
        value: 'true'
        no_extra_spaces: true
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020032
      - NIST-800-53-AC-23
      - NIST-800-53-CM-6(a)
      - dconf_gnome_disable_user_list
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME3 disablement of Login User List
      lineinfile:
        path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/login-screen/disable-user-list$
        line: /org/gnome/login-screen/disable-user-list
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020032
      - NIST-800-53-AC-23
      - NIST-800-53-CM-6(a)
      - dconf_gnome_disable_user_list
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020032
      - NIST-800-53-AC-23
      - NIST-800-53-CM-6(a)
      - dconf_gnome_disable_user_list
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Detect if removal-action can be found on /etc/dconf/db/local.d/
      find:
        path: /etc/dconf/db/local.d/
        contains: ^\s*removal-action
      register: dconf_gnome_lock_screen_on_smartcard_removal_config_files
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Configure removal-action - default file
      ini_file:
        dest: /etc/dconf/db/local.d//00-security-settings
        section: org/gnome/settings-daemon/peripherals/smartcard
        option: removal-action
        value: '''lock-screen'''
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - dconf_gnome_lock_screen_on_smartcard_removal_config_files is defined and dconf_gnome_lock_screen_on_smartcard_removal_config_files.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Configure removal-action - existing files
      ini_file:
        dest: '{{ item.path }}'
        section: org/gnome/settings-daemon/peripherals/smartcard
        option: removal-action
        value: '''lock-screen'''
        create: true
      with_items: '{{ dconf_gnome_lock_screen_on_smartcard_removal_config_files.files
        }}'
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - dconf_gnome_lock_screen_on_smartcard_removal_config_files is defined and dconf_gnome_lock_screen_on_smartcard_removal_config_files.matched
        > 0
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Detect if lock for removal-action can be found on /etc/dconf/db/local.d/
      find:
        path: /etc/dconf/db/local.d/locks
        contains: ^\s*removal-action
      register: dconf_gnome_lock_screen_on_smartcard_removal_lock_files
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification removal-action - default file
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/settings-daemon/peripherals/smartcard/removal-action$
        line: /org/gnome/settings-daemon/peripherals/smartcard/removal-action
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - dconf_gnome_lock_screen_on_smartcard_removal_lock_files is defined and dconf_gnome_lock_screen_on_smartcard_removal_lock_files.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification removal-action - existing files
      lineinfile:
        path: '{{ item.path }}'
        regexp: ^/org/gnome/settings-daemon/peripherals/smartcard/removal-action$
        line: /org/gnome/settings-daemon/peripherals/smartcard/removal-action
        create: true
      with_items: '{{ dconf_gnome_lock_screen_on_smartcard_removal_lock_files.files }}'
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - dconf_gnome_lock_screen_on_smartcard_removal_lock_files is defined and dconf_gnome_lock_screen_on_smartcard_removal_lock_files.matched
        > 0
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update - removal-action
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020050
      - dconf_gnome_lock_screen_on_smartcard_removal
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010820
      - NIST-800-171-3.1.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - gnome_gdm_disable_automatic_login
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy

    - name: Disable GDM Automatic Login
      ini_file:
        dest: /etc/gdm/custom.conf
        section: daemon
        option: AutomaticLoginEnable
        value: 'false'
        no_extra_spaces: true
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-010820
      - NIST-800-171-3.1.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - gnome_gdm_disable_automatic_login
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020060
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_idle_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Set GNOME3 Screensaver Inactivity Timeout
      ini_file:
        dest: /etc/dconf/db/local.d/00-security-settings
        section: org/gnome/desktop/session
        option: idle-delay
        value: uint32 {{ inactivity_timeout_value }}
        create: true
        no_extra_spaces: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020060
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_idle_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020060
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_idle_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020031
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Set GNOME3 Screensaver Lock Delay After Activation Period
      ini_file:
        dest: /etc/dconf/db/local.d/00-security-settings
        section: org/gnome/desktop/screensaver
        option: lock-delay
        value: uint32 {{ var_screensaver_lock_delay }}
        create: true
        no_extra_spaces: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020031
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020031
      - NIST-800-171-3.1.10
      - NIST-800-53-AC-11(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_delay
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution == 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Enable GNOME3 Screensaver Lock After Idle Period
      ini_file:
        dest: /etc/dconf/db/local.d/00-security-settings
        section: org/gnome/desktop/screensaver
        option: lock-enabled
        value: 'true'
        create: true
        no_extra_spaces: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution != 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME lock-enabled
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/desktop/screensaver/lock-enabled$
        line: /org/gnome/desktop/screensaver/lock-enabled
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution != 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Enable GNOME3 Screensaver Lock After Idle Period
      ini_file:
        dest: /etc/dconf/db/local.d/00-security-settings
        section: org/gnome/desktop/lockdown
        option: disable-lock-screen
        value: 'false'
        create: true
        no_extra_spaces: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution == 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME disable-lock-screen
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/desktop/lockdown/disable-lock-screen$
        line: /org/gnome/desktop/lockdown/disable-lock-screen
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution == 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Check GNOME3 screenserver disable-lock-screen false
      command: gsettings get org.gnome.desktop.lockdown disable-lock-screen
      register: cmd_out
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution == 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Update GNOME3 screenserver disable-lock-screen false
      command: gsettings set org.gnome.desktop.lockdown disable-lock-screen false
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_distribution == 'SLES'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020030
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_screensaver_lock_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020082
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - dconf_gnome_screensaver_lock_locked
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME Screensaver lock-enabled
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/desktop/screensaver/lock-enabled$
        line: /org/gnome/desktop/screensaver/lock-enabled
        create: true
      when: '"gdm" in ansible_facts.packages'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020082
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - dconf_gnome_screensaver_lock_locked
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when: '"gdm" in ansible_facts.packages'
      tags:
      - CJIS-5.5.5
      - DISA-STIG-RHEL-08-020082
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - dconf_gnome_screensaver_lock_locked
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020080
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - dconf_gnome_screensaver_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME lock-delay
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/desktop/screensaver/lock-delay$
        line: /org/gnome/desktop/screensaver/lock-delay
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020080
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - dconf_gnome_screensaver_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020080
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - dconf_gnome_screensaver_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020081
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_session_idle_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME Session idle-delay
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/desktop/session/idle-delay$
        line: /org/gnome/desktop/session/idle-delay
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020081
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_session_idle_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-020081
      - NIST-800-171-3.1.10
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - dconf_gnome_session_idle_user_locks
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040171
      - NIST-800-171-3.1.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - dconf_gnome_disable_ctrlaltdel_reboot
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy

    - name: Disable Ctrl-Alt-Del Reboot Key Sequence in GNOME3
      ini_file:
        dest: /etc/dconf/db/local.d/00-security-settings
        section: org/gnome/settings-daemon/plugins/media-keys
        option: logout
        value: '['''']'
        create: true
        no_extra_spaces: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040171
      - NIST-800-171-3.1.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - dconf_gnome_disable_ctrlaltdel_reboot
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME disablement of Ctrl-Alt-Del
      lineinfile:
        path: /etc/dconf/db/local.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/settings-daemon/plugins/media-keys/logout$
        line: /org/gnome/settings-daemon/plugins/media-keys/logout
        create: true
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040171
      - NIST-800-171-3.1.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - dconf_gnome_disable_ctrlaltdel_reboot
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when:
      - '"gdm" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040171
      - NIST-800-171-3.1.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - dconf_gnome_disable_ctrlaltdel_reboot
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy


    - name: Find /etc/sudoers.d/ files
      ansible.builtin.find:
        paths:
        - /etc/sudoers.d/
      register: sudoers
      tags:
      - DISA-STIG-RHEL-08-010381
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-11
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_remove_no_authenticate

    - name: Remove lines containing !authenticate from sudoers files
      ansible.builtin.replace:
        regexp: (^(?!#).*[\s]+\!authenticate.*$)
        replace: '# \g<1>'
        path: '{{ item.path }}'
        validate: /usr/sbin/visudo -cf %s
      with_items:
      - path: /etc/sudoers
      - '{{ sudoers.files }}'
      tags:
      - DISA-STIG-RHEL-08-010381
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-11
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_remove_no_authenticate


    - name: Find /etc/sudoers.d/ files
      ansible.builtin.find:
        paths:
        - /etc/sudoers.d/
      register: sudoers
      tags:
      - DISA-STIG-RHEL-08-010380
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-11
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_remove_nopasswd

    - name: Remove lines containing NOPASSWD from sudoers files
      ansible.builtin.replace:
        regexp: (^(?!#).*[\s]+NOPASSWD[\s]*\:.*$)
        replace: '# \g<1>'
        path: '{{ item.path }}'
        validate: /usr/sbin/visudo -cf %s
      with_items:
      - path: /etc/sudoers
      - '{{ sudoers.files }}'
      tags:
      - DISA-STIG-RHEL-08-010380
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-11
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_remove_nopasswd


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication


    - name: Require Re-Authentication When Using the sudo Command - Find /etc/sudoers.d/*
        files containing 'Defaults timestamp_timeout'
      ansible.builtin.find:
        path: /etc/sudoers.d
        patterns: '*'
        contains: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
      register: sudoers_d_defaults_timestamp_timeout
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication

    - name: Require Re-Authentication When Using the sudo Command - Remove 'Defaults timestamp_timeout'
        from /etc/sudoers.d/* files
      ansible.builtin.lineinfile:
        path: '{{ item.path }}'
        regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
        state: absent
      with_items: '{{ sudoers_d_defaults_timestamp_timeout.files }}'
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication

    - name: Require Re-Authentication When Using the sudo Command - Ensure timestamp_timeout
        has the appropriate value in /etc/sudoers
      ansible.builtin.lineinfile:
        path: /etc/sudoers
        regexp: ^[\s]*Defaults\s(.*)\btimestamp_timeout[\s]*=[\s]*[-]?\w+\b(.*)$
        line: Defaults \1timestamp_timeout={{ var_sudo_timestamp_timeout }}\2
        validate: /usr/sbin/visudo -cf %s
        backrefs: true
      register: edit_sudoers_timestamp_timeout_option
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication

    - name: Require Re-Authentication When Using the sudo Command - Enable timestamp_timeout
        option with correct value in /etc/sudoers
      ansible.builtin.lineinfile:
        path: /etc/sudoers
        line: Defaults timestamp_timeout={{ var_sudo_timestamp_timeout }}
        validate: /usr/sbin/visudo -cf %s
      when:
      - '"sudo" in ansible_facts.packages'
      - |
        edit_sudoers_timestamp_timeout_option is defined and not edit_sudoers_timestamp_timeout_option.changed
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication

    - name: Require Re-Authentication When Using the sudo Command - Remove timestamp_timeout
        wrong values in /etc/sudoers
      ansible.builtin.lineinfile:
        path: /etc/sudoers
        regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=[\s]*(?!{{ var_sudo_timestamp_timeout
          }}\b)[-]?\w+\b.*$
        state: absent
        validate: /usr/sbin/visudo -cf %s
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010384
      - NIST-800-53-IA-11
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudo_require_reauthentication


    - name: Check for duplicate values
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^#includedir.*$
        state: absent
      check_mode: true
      changed_when: false
      register: dupes
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Deduplicate values from /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^#includedir.*$
        state: absent
      when: dupes.found is defined and dupes.found > 1
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Insert correct line into /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^#includedir.*$
        line: '#includedir /etc/sudoers.d'
        state: present
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Ensure sudoers doesn't include other non-default file
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^[#@]include[\s]+.*$
        state: absent
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Ensure sudoers doesn't have non-default includedir
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^@includedir[\s]+.*$
        state: absent
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Find out if /etc/sudoers.d/* files contain file or directory includes
      find:
        path: /etc/sudoers.d
        patterns: '*'
        contains: ^[#@]include(dir)?\s.*$
      register: sudoers_d_includes
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir

    - name: Remove found occurrences of file and directory includes from /etc/sudoers.d/*
        files
      lineinfile:
        path: '{{ item.path }}'
        regexp: ^[#@]include(dir)?\s.*$
        state: absent
      with_items: '{{ sudoers_d_includes.files }}'
      tags:
      - DISA-STIG-RHEL-08-010379
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sudoers_default_includedir


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Find out if /etc/sudoers.d/* files contain Defaults targetpw to be deduplicated
      find:
        path: /etc/sudoers.d
        patterns: '*'
        contains: ^Defaults targetpw$
      register: sudoers_d_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove found occurrences of Defaults targetpw from /etc/sudoers.d/* files
      lineinfile:
        path: '{{ item.path }}'
        regexp: ^Defaults targetpw$
        state: absent
      with_items: '{{ sudoers_d_defaults.files }}'
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Find out if /etc/sudoers.d/* files contain Defaults rootpw to be deduplicated
      find:
        path: /etc/sudoers.d
        patterns: '*'
        contains: ^Defaults rootpw$
      register: sudoers_d_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove found occurrences of Defaults rootpw from /etc/sudoers.d/* files
      lineinfile:
        path: '{{ item.path }}'
        regexp: ^Defaults rootpw$
        state: absent
      with_items: '{{ sudoers_d_defaults.files }}'
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Find out if /etc/sudoers.d/* files contain Defaults runaspw to be deduplicated
      find:
        path: /etc/sudoers.d
        patterns: '*'
        contains: ^Defaults runaspw$
      register: sudoers_d_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove found occurrences of Defaults runaspw from /etc/sudoers.d/* files
      lineinfile:
        path: '{{ item.path }}'
        regexp: ^Defaults runaspw$
        state: absent
      with_items: '{{ sudoers_d_defaults.files }}'
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove any ocurrences of Defaults targetpw in /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        regexp: ^Defaults targetpw$
        validate: /usr/sbin/visudo -cf %s
        state: absent
      register: sudoers_file_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove any ocurrences of Defaults rootpw in /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        regexp: ^Defaults rootpw$
        validate: /usr/sbin/visudo -cf %s
        state: absent
      register: sudoers_file_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Remove any ocurrences of Defaults runaspw in /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        regexp: ^Defaults runaspw$
        validate: /usr/sbin/visudo -cf %s
        state: absent
      register: sudoers_file_defaults
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Check for duplicate values
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !targetpw$
        state: absent
      check_mode: true
      changed_when: false
      register: dupes
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Deduplicate values from /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !targetpw$
        state: absent
      when:
      - '"sudo" in ansible_facts.packages'
      - dupes.found is defined and dupes.found > 1
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Insert correct line into /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !targetpw$
        line: Defaults !targetpw
        state: present
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Check for duplicate values
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !rootpw$
        state: absent
      check_mode: true
      changed_when: false
      register: dupes
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Deduplicate values from /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !rootpw$
        state: absent
      when:
      - '"sudo" in ansible_facts.packages'
      - dupes.found is defined and dupes.found > 1
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Insert correct line into /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !rootpw$
        line: Defaults !rootpw
        state: present
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Check for duplicate values
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !runaspw$
        state: absent
      check_mode: true
      changed_when: false
      register: dupes
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Deduplicate values from /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !runaspw$
        state: absent
      when:
      - '"sudo" in ansible_facts.packages'
      - dupes.found is defined and dupes.found > 1
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd

    - name: Insert correct line into /etc/sudoers
      lineinfile:
        path: /etc/sudoers
        create: false
        regexp: ^Defaults !runaspw$
        line: Defaults !runaspw
        state: present
      when: '"sudo" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010383
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sudoers_validate_passwd


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010472
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_rng-tools_installed

    - name: Ensure rng-tools is installed
      package:
        name: rng-tools
        state: present
      when: ( "kernel" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-010472
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_rng-tools_installed


    - name: Ensure abrt-addon-ccpp is removed
      package:
        name: abrt-addon-ccpp
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_abrt-addon-ccpp_removed


    - name: Ensure abrt-addon-kerneloops is removed
      package:
        name: abrt-addon-kerneloops
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_abrt-addon-kerneloops_removed


    - name: Ensure abrt-cli is removed
      package:
        name: abrt-cli
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_abrt-cli_removed


    - name: Ensure abrt-plugin-sosreport is removed
      package:
        name: abrt-plugin-sosreport
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_abrt-plugin-sosreport_removed


    - name: Ensure gssproxy is removed
      package:
        name: gssproxy
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040370
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_gssproxy_removed


    - name: Ensure iprutils is removed
      package:
        name: iprutils
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040380
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_iprutils_removed


    - name: Ensure krb5-workstation is removed
      package:
        name: krb5-workstation
        state: absent
      tags:
      - DISA-STIG-RHEL-08-010162
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_krb5-workstation_removed


    - name: Ensure libreport-plugin-logger is removed
      package:
        name: libreport-plugin-logger
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_libreport-plugin-logger_removed


    - name: Ensure libreport-plugin-rhtsupport is removed
      package:
        name: libreport-plugin-rhtsupport
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_libreport-plugin-rhtsupport_removed


    - name: Ensure python3-abrt-addon is removed
      package:
        name: python3-abrt-addon
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_python3-abrt-addon_removed


    - name: Ensure tuned is removed
      package:
        name: tuned
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040390
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_tuned_removed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010440
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-2(6)
      - clean_components_post_updating
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure yum Removes Previous Package Versions - Ensure YUM Removes Previous
        Package Versions
      ansible.builtin.lineinfile:
        dest: /etc/yum.conf
        regexp: ^#?clean_requirements_on_remove
        line: clean_requirements_on_remove=1
        insertafter: \[main\]
        create: true
      when: '"yum" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010440
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-2(6)
      - clean_components_post_updating
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Read permission of GPG key directory
      stat:
        path: /etc/pki/rpm-gpg/
      register: gpg_key_directory_permission
      check_mode: false
      tags:
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - ensure_almalinux_gpgkey_installed
      - high_severity
      - medium_complexity
      - medium_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Read signatures in GPG key
      command: gpg --show-keys --with-fingerprint --with-colons "/etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux"
      args:
        warn: false
      changed_when: false
      register: gpg_fingerprints
      check_mode: false
      tags:
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - ensure_almalinux_gpgkey_installed
      - high_severity
      - medium_complexity
      - medium_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Set Fact - Installed GPG Fingerprints
      set_fact:
        gpg_installed_fingerprints: |-
          {{ gpg_fingerprints.stdout | regex_findall('^pub.*
          (?:^fpr[:]*)([0-9A-Fa-f]*)', '\1') | list }}
      tags:
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - ensure_almalinux_gpgkey_installed
      - high_severity
      - medium_complexity
      - medium_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Set Fact - Valid fingerprints
      set_fact:
        gpg_valid_fingerprints: ("5E9B8F5617B5066CE92057C3488FCF7C3ABB34F8" "BC5EDDCADF502C077F1582882AE81E8ACED7258B")
      tags:
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - ensure_almalinux_gpgkey_installed
      - high_severity
      - medium_complexity
      - medium_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Import AlmaLinux GPG key
      rpm_key:
        state: present
        key: /etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux
      when:
      - gpg_key_directory_permission.stat.mode <= '0755'
      - (gpg_installed_fingerprints | difference(gpg_valid_fingerprints)) | length ==
        0
      - gpg_installed_fingerprints | length > 0
      - ansible_distribution == "AlmaLinux"
      tags:
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - ensure_almalinux_gpgkey_installed
      - high_severity
      - medium_complexity
      - medium_disruption
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.4.1
      - DISA-STIG-RHEL-08-010370
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - configure_strategy
      - ensure_gpgcheck_globally_activated
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed

    - name: Ensure GPG check is globally activated
      ini_file:
        dest: /etc/yum.conf
        section: main
        option: gpgcheck
        value: 1
        no_extra_spaces: true
        create: false
      when: '"yum" in ansible_facts.packages'
      tags:
      - CJIS-5.10.4.1
      - DISA-STIG-RHEL-08-010370
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - configure_strategy
      - ensure_gpgcheck_globally_activated
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010371
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - ensure_gpgcheck_local_packages
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy

    - name: Ensure GPG check Enabled for Local Packages (yum)
      block:

      - name: Check stats of yum
        stat:
          path: /etc/yum.conf
        register: pkg

      - name: Check if config file of yum is a symlink
        ansible.builtin.set_fact:
          pkg_config_file_symlink: '{{ pkg.stat.lnk_target if pkg.stat.lnk_target is match("^/.*")
            else "/etc/yum.conf" | dirname ~ "/" ~ pkg.stat.lnk_target }}'
        when: pkg.stat.lnk_target is defined

      - name: Ensure GPG check Enabled for Local Packages (yum)
        ini_file:
          dest: '{{ pkg_config_file_symlink |  default("/etc/yum.conf") }}'
          section: main
          option: localpkg_gpgcheck
          value: 1
          no_extra_spaces: true
          create: true
      when: '"yum" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010371
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - ensure_gpgcheck_local_packages
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
      - unknown_strategy


    - name: Grep for yum repo section names
      shell: |
        set -o pipefail
        grep -HEr '^\[.+\]' -r /etc/yum.repos.d/
      register: repo_grep_results
      failed_when: repo_grep_results.rc not in [0, 1]
      changed_when: false
      tags:
      - CJIS-5.10.4.1
      - DISA-STIG-RHEL-08-010370
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - enable_strategy
      - ensure_gpgcheck_never_disabled
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed

    - name: Set gpgcheck=1 for each yum repo
      ini_file:
        path: '{{ item[0] }}'
        section: '{{ item[1] }}'
        option: gpgcheck
        value: '1'
        no_extra_spaces: true
      loop: '{{ repo_grep_results.stdout |regex_findall( ''(.+\.repo):\[(.+)\]\n?'' )
        if repo_grep_results is not skipped else [] }}'
      when: repo_grep_results is not skipped
      tags:
      - CJIS-5.10.4.1
      - DISA-STIG-RHEL-08-010370
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3
      - PCI-DSSv4-6.3.3
      - enable_strategy
      - ensure_gpgcheck_never_disabled
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed


    - name: Enable authselect - Check Current authselect Profile
      ansible.builtin.command:
        cmd: authselect current
      register: result_authselect_current
      changed_when: false
      failed_when: false
      tags:
      - NIST-800-53-AC-3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - configure_strategy
      - enable_authselect
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Enable authselect - Try to Select an authselect Profile
      ansible.builtin.command:
        cmd: authselect select "{{ var_authselect_profile }}"
      register: result_authselect_select
      changed_when: result_authselect_select.rc == 0
      failed_when: false
      when: result_authselect_current.rc != 0
      tags:
      - NIST-800-53-AC-3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - configure_strategy
      - enable_authselect
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Enable authselect - Verify If pam Has Been Altered
      ansible.builtin.command:
        cmd: rpm -qV pam
      register: result_altered_authselect
      changed_when: false
      failed_when: false
      when:
      - result_authselect_select is not skipped
      - result_authselect_select.rc != 0
      tags:
      - NIST-800-53-AC-3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - configure_strategy
      - enable_authselect
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Enable authselect - Informative Message Based on authselect Integrity Check
      ansible.builtin.assert:
        that:
        - result_authselect_current.rc == 0 or result_altered_authselect is skipped or
          result_altered_authselect.rc == 0
        fail_msg:
        - authselect is not used but files from the 'pam' package have been altered, so
          the authselect configuration won't be forced.
      tags:
      - NIST-800-53-AC-3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - configure_strategy
      - enable_authselect
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Enable authselect - Force authselect Profile Selection
      ansible.builtin.command:
        cmd: authselect select --force "{{ var_authselect_profile }}"
      when:
      - result_authselect_current.rc != 0
      - result_authselect_select.rc != 0
      - result_altered_authselect.rc == 0
      tags:
      - NIST-800-53-AC-3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - configure_strategy
      - enable_authselect
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010060
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - banner_etc_issue
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Modify the System Login Banner - Ensure Correct Banner
      copy:
        dest: /etc/issue
        content: '{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
          "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
          "\n") | regex_replace("\\", "") | wordwrap() }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010060
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - banner_etc_issue
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010049
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(b)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_banner_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Enable GNOME3 Login Warning Banner
      ini_file:
        dest: /etc/dconf/db/gdm.d/00-security-settings
        section: org/gnome/login-screen
        option: banner-message-enable
        value: 'true'
        create: true
        no_extra_spaces: true
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010049
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(b)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_banner_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of GNOME banner-message-enabled
      lineinfile:
        path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/login-screen/banner-message-enable$
        line: /org/gnome/login-screen/banner-message-enable
        create: true
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010049
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(b)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_banner_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010049
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(b)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_banner_enabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Set the GNOME3 Login Warning Banner Text
      file:
        path: /etc/dconf/db/{{ item }}
        owner: root
        group: root
        mode: 493
        state: directory
      with_items:
      - gdm.d
      - gdm.d/locks
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Set the GNOME3 Login Warning Banner Text
      file:
        path: /etc/dconf/db/gdm.d/{{ item }}
        owner: root
        group: root
        mode: 420
        state: touch
      with_items:
      - 00-security-settings
      - locks/00-security-settings-lock
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Set the GNOME3 Login Warning Banner Text
      ini_file:
        dest: /etc/dconf/db/gdm.d/00-security-settings
        section: org/gnome/login-screen
        option: banner-message-text
        value: '''{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
          "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
          "(n)*") | regex_replace("\\", "") | regex_replace("\(n\)\*", "\\n") }}'''
        create: true
        no_extra_spaces: true
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Prevent user modification of the GNOME3 Login Warning Banner Text
      lineinfile:
        path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
        regexp: ^/org/gnome/login-screen/banner-message-text$
        line: /org/gnome/login-screen/banner-message-text
        create: true
        state: present
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy

    - name: Dconf Update
      command: dconf update
      when: '"gdm" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010050
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - dconf_gnome_login_banner_text
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010385
      - NIST-800-53-IA-11
      - disallow_bypass_password_sudo
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Check for pam_succeed_if entry
      ansible.builtin.lineinfile:
        path: /etc/pam.d/sudo
        create: false
        regexp: pam_succeed_if
        state: absent
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010385
      - NIST-800-53-IA-11
      - disallow_bypass_password_sudo
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020340
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - PCI-DSS-Req-10.2.4
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.4
      - configure_strategy
      - display_login_attempts
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed

    - name: Ensure PAM Displays Last Logon/Access Notification - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020340
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - PCI-DSS-Req-10.2.4
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.4
      - configure_strategy
      - display_login_attempts
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed

    - name: Ensure PAM Displays Last Logon/Access Notification - Collect the Available
        authselect Features
      ansible.builtin.command:
        cmd: authselect list-features sssd
      register: result_authselect_available_features
      changed_when: false
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020340
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - PCI-DSS-Req-10.2.4
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.4
      - configure_strategy
      - display_login_attempts
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed

    - name: Ensure PAM Displays Last Logon/Access Notification - Configure pam_lastlog.so
        Using authselect Feature
      block:

      - name: Ensure PAM Displays Last Logon/Access Notification - Check integrity of
          authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Ensure PAM Displays Last Logon/Access Notification - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Ensure PAM Displays Last Logon/Access Notification - Get authselect Features
          Currently Enabled
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Ensure PAM Displays Last Logon/Access Notification - Ensure "with-silent-lastlog"
          Feature is Disabled Using authselect Tool
        ansible.builtin.command:
          cmd: authselect disable-feature with-silent-lastlog
        register: result_authselect_disable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is search("with-silent-lastlog")

      - name: Ensure PAM Displays Last Logon/Access Notification - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_disable_feature_cmd is not skipped
        - result_authselect_disable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      - result_authselect_available_features.stdout is search("with-silent-lastlog")
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020340
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - PCI-DSS-Req-10.2.4
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.4
      - configure_strategy
      - display_login_attempts
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed

    - name: Ensure PAM Displays Last Logon/Access Notification - Configure pam_lastlog.so
        in appropriate PAM files
      block:

      - name: Ensure PAM Displays Last Logon/Access Notification - Define the PAM file
          to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/postlogin

      - name: Ensure PAM Displays Last Logon/Access Notification - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Ensure PAM Displays Last Logon/Access Notification - Ensure authselect custom
          profile is used if authselect is present
        block:

        - name: Ensure PAM Displays Last Logon/Access Notification - Check integrity of
            authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Ensure PAM Displays Last Logon/Access Notification - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Ensure PAM Displays Last Logon/Access Notification - Get authselect current
            profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Ensure PAM Displays Last Logon/Access Notification - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Ensure PAM Displays Last Logon/Access Notification - Define the new authselect
            custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Ensure PAM Displays Last Logon/Access Notification - Get authselect current
            features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM Displays Last Logon/Access Notification - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM Displays Last Logon/Access Notification - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM Displays Last Logon/Access Notification - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Ensure PAM Displays Last Logon/Access Notification - Change the PAM file
            to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Ensure PAM Displays Last Logon/Access Notification - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: '[default=1]'

      - name: Ensure PAM Displays Last Logon/Access Notification - Check if expected PAM
          module line is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*session\s+{{ pam_module_control | regex_escape() }}\s+pam_lastlog.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Ensure PAM Displays Last Logon/Access Notification - Include or update the
          PAM module line in {{ pam_file_path }}
        block:

        - name: Ensure PAM Displays Last Logon/Access Notification - Check if required
            PAM module line is present in {{ pam_file_path }} with different control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*session\s+.*\s+pam_lastlog.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure the correct
            control for the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*session\s+).*(\bpam_lastlog.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure the required
            PAM module line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            insertafter: ^\s*session\s+.*pam_succeed_if\.so.*
            line: session    {{ pam_module_control }}    pam_lastlog.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Ensure PAM Displays Last Logon/Access Notification - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Ensure PAM Displays Last Logon/Access Notification - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: '[default=1]'

      - name: Ensure PAM Displays Last Logon/Access Notification - Check if the required
          PAM module option is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*session\s+{{ pam_module_control | regex_escape() }}\s+pam_lastlog.so\s*.*\sshowfailed\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_display_login_attempts_option_present

      - name: Ensure PAM Displays Last Logon/Access Notification - Ensure the "showfailed"
          PAM option for "pam_lastlog.so" is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*session\s+{{ pam_module_control | regex_escape() }}\s+pam_lastlog.so.*)
          line: \1 showfailed
          state: present
        register: result_pam_display_login_attempts_add
        when:
        - result_pam_module_display_login_attempts_option_present.found == 0

      - name: Ensure PAM Displays Last Logon/Access Notification - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: '[default=1]'

      - name: Ensure PAM Displays Last Logon/Access Notification - Ensure the "silent"
          option from "pam_lastlog.so" is not present in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*session.*{{ pam_module_control | regex_escape() }}.*pam_lastlog.so.*)\bsilent\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020340
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - PCI-DSS-Req-10.2.4
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.4
      - configure_strategy
      - display_login_attempts
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed


    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Check if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      tags:
      - DISA-STIG-RHEL-08-020026
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_password_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Remediation where authselect tool is present
      block:

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Check integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Informative message based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Ensure "with-faillock" feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when: result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020026
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_password_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Remediation where authselect tool is not present
      block:

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Check if pam_faillock.so is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Enable pam_faillock.so preauth editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Enable pam_faillock.so authfail editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
          File. - Enable pam_faillock.so account section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when: not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020026
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_password_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Check if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      tags:
      - DISA-STIG-RHEL-08-020025
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_system_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Remediation where authselect tool is present
      block:

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Check integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Informative message based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Ensure "with-faillock" feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when: result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020025
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_system_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Remediation where authselect tool is not present
      block:

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Check if pam_faillock.so is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Enable pam_faillock.so preauth editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Enable pam_faillock.so authfail editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
          File. - Enable pam_faillock.so account section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when: not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020025
      - NIST-800-53-AC-7 (a)
      - account_password_pam_faillock_system_auth
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Get directories from faillock
      ansible.builtin.shell: grep -oP '^\s*(?:auth.*pam_faillock.so.*)?dir\s*=\s*(\S+)'
        "{{ item }}" | sed -r 's/.*=\s*(\S+)/\1/'
      register: faillock_output
      with_items:
      - /etc/security/faillock.conf
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Create a list directories from faillock
      ansible.builtin.set_fact:
        list_faillock_dir: '{{ faillock_output.results | map(attribute=''stdout_lines'')
          | flatten }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Create directories for faillock
      ansible.builtin.file:
        path: '{{ item }}'
        state: directory
      with_items: '{{ list_faillock_dir }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - item != ""
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Set up SELinux context for faillock
      ansible.builtin.shell: |-
        if ! semanage fcontext -a -t faillog_t "{{ item }}(/.*)?"; then
          semanage fcontext -m -t faillog_t "{{ item }}(/.*)?"
        fi
      with_items: '{{ list_faillock_dir }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - item != ""
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Restore SELinux context
      ansible.builtin.command: restorecon -R -v "{{ item }}"
      with_items: '{{ list_faillock_dir }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - item != ""
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: An SELinux Context must be configured for the pam_faillock.so records directory
        - Verify pam_faillock.so configuration
      ansible.builtin.debug:
        msg: |-
          "The pam_faillock.so dir option is not set in the system.
          If this is not expected, make sure pam_faillock.so is properly configured."
      when:
      - '"kernel" in ansible_facts.packages'
      - list_faillock_dir | length == 0
      tags:
      - DISA-STIG-RHEL-08-020027
      - DISA-STIG-RHEL-08-020028
      - NIST-800-53-AC-7 (a)
      - account_password_selinux_faillock_dir
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - Collect the available authselect features'
      ansible.builtin.command:
        cmd: authselect list-features sssd
      register: result_authselect_available_features
      changed_when: false
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so using authselect
        feature'
      block:

      - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current
          profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: 'Limit Password Reuse: password-auth - Informative message based on the
          authselect integrity check result'
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: password-auth - Get authselect current features'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: password-auth - Ensure "with-pwhistory" feature is
          enabled using authselect tool'
        ansible.builtin.command:
          cmd: authselect enable-feature with-pwhistory
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-pwhistory")

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      - result_authselect_available_features.stdout is search("with-pwhistory")
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so in appropriate
        PAM files'
      block:

      - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
          as a local fact'
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
          tool'
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
          is used if authselect is present'
        block:

        - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current
            profile'
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: 'Limit Password Reuse: password-auth - Informative message based on the
            authselect integrity check result'
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: 'Limit Password Reuse: password-auth - Define the current authselect profile
            as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: 'Limit Password Reuse: password-auth - Define the new authselect custom
            profile as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Get authselect current features
            to also enable them in the custom profile'
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Check if any custom profile with
            the same name was already created'
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
            based on the current profile'
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom profile
            is selected'
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: password-auth - Restore the authselect features
            in the custom profile'
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited
            according to the custom authselect profile'
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Define a fact for control already
          filtered in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0]
            }}'

      - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line
          is present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: 'Limit Password Reuse: password-auth - Include or update the PAM module
          line in {{ pam_file_path }}'
        block:

        - name: 'Limit Password Reuse: password-auth - Check if required PAM module line
            is present in {{ pam_file_path }} with different control'
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: 'Limit Password Reuse: password-auth - Ensure the correct control for
            the required PAM module line in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module
            line is included in {{ pam_file_path }}'
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            insertafter: ^password.*requisite.*pam_pwquality\.so
            line: password    {{ pam_module_control }}    pam_pwhistory.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - |
        (result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - Check the presence of /etc/security/pwhistory.conf
        file'
      ansible.builtin.stat:
        path: /etc/security/pwhistory.conf
      register: result_pwhistory_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured
        in /etc/security/pwhistory.conf file'
      block:

      - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember
          parameter in /etc/security/pwhistory.conf'
        ansible.builtin.lineinfile:
          path: /etc/security/pwhistory.conf
          regexp: ^\s*remember\s*=
          line: remember = {{ var_password_pam_remember }}
          state: present

      - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember
          parameter is removed from PAM files'
        block:

        - name: 'Limit Password Reuse: password-auth - Check if /etc/pam.d/password-auth
            file is present'
          ansible.builtin.stat:
            path: /etc/pam.d/password-auth
          register: result_pam_file_present

        - name: 'Limit Password Reuse: password-auth - Check the proper remediation for
            the system'
          block:

          - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
              as a local fact'
            ansible.builtin.set_fact:
              pam_file_path: /etc/pam.d/password-auth

          - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
              tool'
            ansible.builtin.stat:
              path: /usr/bin/authselect
            register: result_authselect_present

          - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
              is used if authselect is present'
            block:

            - name: 'Limit Password Reuse: password-auth - Check integrity of authselect
                current profile'
              ansible.builtin.command:
                cmd: authselect check
              register: result_authselect_check_cmd
              changed_when: false
              failed_when: false

            - name: 'Limit Password Reuse: password-auth - Informative message based on
                the authselect integrity check result'
              ansible.builtin.assert:
                that:
                - result_authselect_check_cmd.rc == 0
                fail_msg:
                - authselect integrity check failed. Remediation aborted!
                - This remediation could not be applied because an authselect profile
                  was not selected or the selected profile is not intact.
                - It is not recommended to manually edit the PAM files when authselect
                  tool is available.
                - In cases where the default authselect profile does not cover a specific
                  demand, a custom authselect profile is recommended.
                success_msg:
                - authselect integrity check passed

            - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
              ansible.builtin.shell:
                cmd: authselect current -r | awk '{ print $1 }'
              register: result_authselect_profile
              changed_when: false
              when:
              - result_authselect_check_cmd is success

            - name: 'Limit Password Reuse: password-auth - Define the current authselect
                profile as a local fact'
              ansible.builtin.set_fact:
                authselect_current_profile: '{{ result_authselect_profile.stdout }}'
                authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
              when:
              - result_authselect_profile is not skipped
              - result_authselect_profile.stdout is match("custom/")

            - name: 'Limit Password Reuse: password-auth - Define the new authselect custom
                profile as a local fact'
              ansible.builtin.set_fact:
                authselect_current_profile: '{{ result_authselect_profile.stdout }}'
                authselect_custom_profile: custom/hardening
              when:
              - result_authselect_profile is not skipped
              - result_authselect_profile.stdout is not match("custom/")

            - name: 'Limit Password Reuse: password-auth - Get authselect current features
                to also enable them in the custom profile'
              ansible.builtin.shell:
                cmd: authselect current | tail -n+3 | awk '{ print $2 }'
              register: result_authselect_features
              changed_when: false
              when:
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")

            - name: 'Limit Password Reuse: password-auth - Check if any custom profile
                with the same name was already created'
              ansible.builtin.stat:
                path: /etc/authselect/{{ authselect_custom_profile }}
              register: result_authselect_custom_profile_present
              changed_when: false
              when:
              - authselect_current_profile is not match("custom/")

            - name: 'Limit Password Reuse: password-auth - Create an authselect custom
                profile based on the current profile'
              ansible.builtin.command:
                cmd: authselect create-profile hardening -b {{ authselect_current_profile
                  }}
              when:
              - result_authselect_check_cmd is success
              - authselect_current_profile is not match("custom/")
              - not result_authselect_custom_profile_present.stat.exists

            - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
                applied'
              ansible.builtin.command:
                cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")
              - authselect_custom_profile is not match(authselect_current_profile)

            - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom
                profile is selected'
              ansible.builtin.command:
                cmd: authselect select {{ authselect_custom_profile }}
              register: result_pam_authselect_select_profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")
              - authselect_custom_profile is not match(authselect_current_profile)

            - name: 'Limit Password Reuse: password-auth - Restore the authselect features
                in the custom profile'
              ansible.builtin.command:
                cmd: authselect enable-feature {{ item }}
              loop: '{{ result_authselect_features.stdout_lines }}'
              register: result_pam_authselect_restore_features
              when:
              - result_authselect_profile is not skipped
              - result_authselect_features is not skipped
              - result_pam_authselect_select_profile is not skipped

            - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
                applied'
              ansible.builtin.command:
                cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - result_pam_authselect_restore_features is not skipped

            - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited
                according to the custom authselect profile'
              ansible.builtin.set_fact:
                pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                  | basename }}
            when:
            - result_authselect_present.stat.exists

          - name: 'Limit Password Reuse: password-auth - Define a fact for control already
              filtered in case filters are used'
            ansible.builtin.set_fact:
              pam_module_control: ''

          - name: 'Limit Password Reuse: password-auth - Ensure the "remember" option
              from "pam_pwhistory.so" is not present in {{ pam_file_path }}'
            ansible.builtin.replace:
              dest: '{{ pam_file_path }}'
              regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
              replace: \1\2
            register: result_pam_option_removal

          - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
              applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b
            when:
            - result_authselect_present.stat.exists
            - result_pam_option_removal is changed
          when:
          - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_pwhistory_conf_check.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured
        in PAM files'
      block:

      - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
          as a local fact'
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
          tool'
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
          is used if authselect is present'
        block:

        - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current
            profile'
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: 'Limit Password Reuse: password-auth - Informative message based on the
            authselect integrity check result'
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: 'Limit Password Reuse: password-auth - Define the current authselect profile
            as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: 'Limit Password Reuse: password-auth - Define the new authselect custom
            profile as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Get authselect current features
            to also enable them in the custom profile'
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Check if any custom profile with
            the same name was already created'
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
            based on the current profile'
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom profile
            is selected'
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: password-auth - Restore the authselect features
            in the custom profile'
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited
            according to the custom authselect profile'
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Define a fact for control already
          filtered in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line
          is present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: 'Limit Password Reuse: password-auth - Include or update the PAM module
          line in {{ pam_file_path }}'
        block:

        - name: 'Limit Password Reuse: password-auth - Check if required PAM module line
            is present in {{ pam_file_path }} with different control'
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: 'Limit Password Reuse: password-auth - Ensure the correct control for
            the required PAM module line in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module
            line is included in {{ pam_file_path }}'
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            line: password    {{ pam_module_control }}    pam_pwhistory.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: 'Limit Password Reuse: password-auth - Define a fact for control already
          filtered in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: 'Limit Password Reuse: password-auth - Check if the required PAM module
          option is present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present

      - name: 'Limit Password Reuse: password-auth - Ensure the "remember" PAM option
          for "pam_pwhistory.so" is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*)
          line: \1 remember={{ var_password_pam_remember }}
          state: present
        register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_add
        when:
        - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present.found
          == 0

      - name: 'Limit Password Reuse: password-auth - Ensure the required value for "remember"
          PAM option from "pam_pwhistory.so" in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*)
          line: \1\2={{ var_password_pam_remember }} \3
        register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_edit
        when:
        - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present.found
          > 0

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - (result_pam_remember_add is defined and result_pam_remember_add.changed) or
          (result_pam_remember_edit is defined and result_pam_remember_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - not result_pwhistory_conf_check.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020220
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - Collect the available authselect features'
      ansible.builtin.command:
        cmd: authselect list-features sssd
      register: result_authselect_available_features
      changed_when: false
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so using authselect
        feature'
      block:

      - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
          profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: 'Limit Password Reuse: system-auth - Informative message based on the authselect
          integrity check result'
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: system-auth - Get authselect current features'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: system-auth - Ensure "with-pwhistory" feature is
          enabled using authselect tool'
        ansible.builtin.command:
          cmd: authselect enable-feature with-pwhistory
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-pwhistory")

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      - result_authselect_available_features.stdout is search("with-pwhistory")
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so in appropriate
        PAM files'
      block:

      - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited as
          a local fact'
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
          tool'
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile is
          used if authselect is present'
        block:

        - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
            profile'
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: 'Limit Password Reuse: system-auth - Informative message based on the
            authselect integrity check result'
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: 'Limit Password Reuse: system-auth - Define the current authselect profile
            as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
            profile as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Get authselect current features to
            also enable them in the custom profile'
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Check if any custom profile with
            the same name was already created'
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
            based on the current profile'
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile
            is selected'
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: system-auth - Restore the authselect features in
            the custom profile'
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
            according to the custom authselect profile'
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Define a fact for control already filtered
          in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0]
            }}'

      - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line is
          present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: 'Limit Password Reuse: system-auth - Include or update the PAM module line
          in {{ pam_file_path }}'
        block:

        - name: 'Limit Password Reuse: system-auth - Check if required PAM module line
            is present in {{ pam_file_path }} with different control'
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: 'Limit Password Reuse: system-auth - Ensure the correct control for the
            required PAM module line in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module line
            is included in {{ pam_file_path }}'
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            insertafter: ^password.*requisite.*pam_pwquality\.so
            line: password    {{ pam_module_control }}    pam_pwhistory.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - |
        (result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - Check the presence of /etc/security/pwhistory.conf
        file'
      ansible.builtin.stat:
        path: /etc/security/pwhistory.conf
      register: result_pwhistory_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured
        in /etc/security/pwhistory.conf file'
      block:

      - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember
          parameter in /etc/security/pwhistory.conf'
        ansible.builtin.lineinfile:
          path: /etc/security/pwhistory.conf
          regexp: ^\s*remember\s*=
          line: remember = {{ var_password_pam_remember }}
          state: present

      - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember
          parameter is removed from PAM files'
        block:

        - name: 'Limit Password Reuse: system-auth - Check if /etc/pam.d/system-auth file
            is present'
          ansible.builtin.stat:
            path: /etc/pam.d/system-auth
          register: result_pam_file_present

        - name: 'Limit Password Reuse: system-auth - Check the proper remediation for
            the system'
          block:

          - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited
              as a local fact'
            ansible.builtin.set_fact:
              pam_file_path: /etc/pam.d/system-auth

          - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
              tool'
            ansible.builtin.stat:
              path: /usr/bin/authselect
            register: result_authselect_present

          - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile
              is used if authselect is present'
            block:

            - name: 'Limit Password Reuse: system-auth - Check integrity of authselect
                current profile'
              ansible.builtin.command:
                cmd: authselect check
              register: result_authselect_check_cmd
              changed_when: false
              failed_when: false

            - name: 'Limit Password Reuse: system-auth - Informative message based on
                the authselect integrity check result'
              ansible.builtin.assert:
                that:
                - result_authselect_check_cmd.rc == 0
                fail_msg:
                - authselect integrity check failed. Remediation aborted!
                - This remediation could not be applied because an authselect profile
                  was not selected or the selected profile is not intact.
                - It is not recommended to manually edit the PAM files when authselect
                  tool is available.
                - In cases where the default authselect profile does not cover a specific
                  demand, a custom authselect profile is recommended.
                success_msg:
                - authselect integrity check passed

            - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
              ansible.builtin.shell:
                cmd: authselect current -r | awk '{ print $1 }'
              register: result_authselect_profile
              changed_when: false
              when:
              - result_authselect_check_cmd is success

            - name: 'Limit Password Reuse: system-auth - Define the current authselect
                profile as a local fact'
              ansible.builtin.set_fact:
                authselect_current_profile: '{{ result_authselect_profile.stdout }}'
                authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
              when:
              - result_authselect_profile is not skipped
              - result_authselect_profile.stdout is match("custom/")

            - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
                profile as a local fact'
              ansible.builtin.set_fact:
                authselect_current_profile: '{{ result_authselect_profile.stdout }}'
                authselect_custom_profile: custom/hardening
              when:
              - result_authselect_profile is not skipped
              - result_authselect_profile.stdout is not match("custom/")

            - name: 'Limit Password Reuse: system-auth - Get authselect current features
                to also enable them in the custom profile'
              ansible.builtin.shell:
                cmd: authselect current | tail -n+3 | awk '{ print $2 }'
              register: result_authselect_features
              changed_when: false
              when:
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")

            - name: 'Limit Password Reuse: system-auth - Check if any custom profile with
                the same name was already created'
              ansible.builtin.stat:
                path: /etc/authselect/{{ authselect_custom_profile }}
              register: result_authselect_custom_profile_present
              changed_when: false
              when:
              - authselect_current_profile is not match("custom/")

            - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
                based on the current profile'
              ansible.builtin.command:
                cmd: authselect create-profile hardening -b {{ authselect_current_profile
                  }}
              when:
              - result_authselect_check_cmd is success
              - authselect_current_profile is not match("custom/")
              - not result_authselect_custom_profile_present.stat.exists

            - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are
                applied'
              ansible.builtin.command:
                cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")
              - authselect_custom_profile is not match(authselect_current_profile)

            - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom
                profile is selected'
              ansible.builtin.command:
                cmd: authselect select {{ authselect_custom_profile }}
              register: result_pam_authselect_select_profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - authselect_current_profile is not match("custom/")
              - authselect_custom_profile is not match(authselect_current_profile)

            - name: 'Limit Password Reuse: system-auth - Restore the authselect features
                in the custom profile'
              ansible.builtin.command:
                cmd: authselect enable-feature {{ item }}
              loop: '{{ result_authselect_features.stdout_lines }}'
              register: result_pam_authselect_restore_features
              when:
              - result_authselect_profile is not skipped
              - result_authselect_features is not skipped
              - result_pam_authselect_select_profile is not skipped

            - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are
                applied'
              ansible.builtin.command:
                cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
              when:
              - result_authselect_check_cmd is success
              - result_authselect_profile is not skipped
              - result_pam_authselect_restore_features is not skipped

            - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
                according to the custom authselect profile'
              ansible.builtin.set_fact:
                pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                  | basename }}
            when:
            - result_authselect_present.stat.exists

          - name: 'Limit Password Reuse: system-auth - Define a fact for control already
              filtered in case filters are used'
            ansible.builtin.set_fact:
              pam_module_control: ''

          - name: 'Limit Password Reuse: system-auth - Ensure the "remember" option from
              "pam_pwhistory.so" is not present in {{ pam_file_path }}'
            ansible.builtin.replace:
              dest: '{{ pam_file_path }}'
              regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
              replace: \1\2
            register: result_pam_option_removal

          - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b
            when:
            - result_authselect_present.stat.exists
            - result_pam_option_removal is changed
          when:
          - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_pwhistory_conf_check.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured
        in PAM files'
      block:

      - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited as
          a local fact'
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
          tool'
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile is
          used if authselect is present'
        block:

        - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
            profile'
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: 'Limit Password Reuse: system-auth - Informative message based on the
            authselect integrity check result'
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: 'Limit Password Reuse: system-auth - Define the current authselect profile
            as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
            profile as a local fact'
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Get authselect current features to
            also enable them in the custom profile'
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Check if any custom profile with
            the same name was already created'
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
            based on the current profile'
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile
            is selected'
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: 'Limit Password Reuse: system-auth - Restore the authselect features in
            the custom profile'
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
            according to the custom authselect profile'
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Define a fact for control already filtered
          in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line is
          present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: 'Limit Password Reuse: system-auth - Include or update the PAM module line
          in {{ pam_file_path }}'
        block:

        - name: 'Limit Password Reuse: system-auth - Check if required PAM module line
            is present in {{ pam_file_path }} with different control'
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: 'Limit Password Reuse: system-auth - Ensure the correct control for the
            required PAM module line in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module line
            is included in {{ pam_file_path }}'
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            line: password    {{ pam_module_control }}    pam_pwhistory.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: 'Limit Password Reuse: system-auth - Define a fact for control already filtered
          in case filters are used'
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: 'Limit Password Reuse: system-auth - Check if the required PAM module option
          is present in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present

      - name: 'Limit Password Reuse: system-auth - Ensure the "remember" PAM option for
          "pam_pwhistory.so" is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*)
          line: \1 remember={{ var_password_pam_remember }}
          state: present
        register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_add
        when:
        - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present.found
          == 0

      - name: 'Limit Password Reuse: system-auth - Ensure the required value for "remember"
          PAM option from "pam_pwhistory.so" in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*)
          line: \1\2={{ var_password_pam_remember }} \3
        register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_edit
        when:
        - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present.found
          > 0

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - (result_pam_remember_add is defined and result_pam_remember_add.changed) or
          (result_pam_remember_edit is defined and result_pam_remember_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - not result_pwhistory_conf_check.stat.exists
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020221
      - NIST-800-171-3.5.8
      - NIST-800-53-IA-5(1)(e)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.5
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.7
      - accounts_password_pam_pwhistory_remember_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Account Lockouts Must Be Logged - Check if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Remediation where authselect tool is present
      block:

      - name: Account Lockouts Must Be Logged - Check integrity of authselect current
          profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Account Lockouts Must Be Logged - Informative message based on the authselect
          integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Account Lockouts Must Be Logged - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Account Lockouts Must Be Logged - Ensure "with-faillock" feature is enabled
          using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when: result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Remediation where authselect tool is not
        present
      block:

      - name: Account Lockouts Must Be Logged - Check if pam_faillock.so is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Account Lockouts Must Be Logged - Enable pam_faillock.so preauth editing
          PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Account Lockouts Must Be Logged - Enable pam_faillock.so authfail editing
          PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Account Lockouts Must Be Logged - Enable pam_faillock.so account section
          editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when: not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Check the presence of /etc/security/faillock.conf
        file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Ensure the pam_faillock.so audit parameter
        in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*audit
        line: audit
        state: present
      when: result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Ensure the pam_faillock.so audit parameter
        not in PAM files
      block:

      - name: Account Lockouts Must Be Logged - Check if /etc/pam.d/system-auth file is
          present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Account Lockouts Must Be Logged - Check the proper remediation for the system
        block:

        - name: Account Lockouts Must Be Logged - Define the PAM file to be edited as
            a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Account Lockouts Must Be Logged - Check if system relies on authselect
            tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Account Lockouts Must Be Logged - Ensure authselect custom profile is
            used if authselect is present
          block:

          - name: Account Lockouts Must Be Logged - Check integrity of authselect current
              profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Account Lockouts Must Be Logged - Informative message based on the authselect
              integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Account Lockouts Must Be Logged - Get authselect current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Account Lockouts Must Be Logged - Define the current authselect profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Account Lockouts Must Be Logged - Define the new authselect custom profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Account Lockouts Must Be Logged - Get authselect current features to
              also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Account Lockouts Must Be Logged - Check if any custom profile with the
              same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Account Lockouts Must Be Logged - Create an authselect custom profile
              based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Account Lockouts Must Be Logged - Ensure the authselect custom profile
              is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Account Lockouts Must Be Logged - Restore the authselect features in
              the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Account Lockouts Must Be Logged - Change the PAM file to be edited according
              to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Account Lockouts Must Be Logged - Define a fact for control already filtered
            in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Account Lockouts Must Be Logged - Ensure the "audit" option from "pam_faillock.so"
            is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\baudit\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Account Lockouts Must Be Logged - Check if /etc/pam.d/password-auth file
          is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Account Lockouts Must Be Logged - Check the proper remediation for the system
        block:

        - name: Account Lockouts Must Be Logged - Define the PAM file to be edited as
            a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Account Lockouts Must Be Logged - Check if system relies on authselect
            tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Account Lockouts Must Be Logged - Ensure authselect custom profile is
            used if authselect is present
          block:

          - name: Account Lockouts Must Be Logged - Check integrity of authselect current
              profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Account Lockouts Must Be Logged - Informative message based on the authselect
              integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Account Lockouts Must Be Logged - Get authselect current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Account Lockouts Must Be Logged - Define the current authselect profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Account Lockouts Must Be Logged - Define the new authselect custom profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Account Lockouts Must Be Logged - Get authselect current features to
              also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Account Lockouts Must Be Logged - Check if any custom profile with the
              same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Account Lockouts Must Be Logged - Create an authselect custom profile
              based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Account Lockouts Must Be Logged - Ensure the authselect custom profile
              is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Account Lockouts Must Be Logged - Restore the authselect features in
              the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Account Lockouts Must Be Logged - Change the PAM file to be edited according
              to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Account Lockouts Must Be Logged - Define a fact for control already filtered
            in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Account Lockouts Must Be Logged - Ensure the "audit" option from "pam_faillock.so"
            is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\baudit\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Account Lockouts Must Be Logged - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when: result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Account Lockouts Must Be Logged - Ensure the pam_faillock.so audit parameter
        in PAM files
      block:

      - name: Account Lockouts Must Be Logged - Check if pam_faillock.so audit parameter
          is already enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*audit
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_audit_parameter_is_present

      - name: Account Lockouts Must Be Logged - Ensure the inclusion of pam_faillock.so
          preauth audit parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 audit
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_audit_parameter_is_present.found == 0
      when: not result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020021
      - NIST-800-53-AC-7 (a)
      - accounts_passwords_pam_faillock_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Check if system relies on authselect
        tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Remediation where authselect
        tool is present
      block:

      - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
          current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Lock Accounts After Failed Password Attempts - Informative message based
          on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Lock Accounts After Failed Password Attempts - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Lock Accounts After Failed Password Attempts - Ensure "with-faillock" feature
          is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Remediation where authselect
        tool is not present
      block:

      - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
          is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so preauth
          editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so authfail
          editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so account
          section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Lock Accounts After Failed Password Attempts - Check the presence of /etc/security/faillock.conf
        file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
        deny parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*deny\s*=
        line: deny = {{ var_accounts_passwords_pam_faillock_deny }}
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
        deny parameter not in PAM files
      block:

      - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/system-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
            be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Lock Accounts After Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom
            profile is used if authselect is present
          block:

          - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
              current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Lock Accounts After Failed Password Attempts - Informative message based
              on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Lock Accounts After Failed Password Attempts - Get authselect current
              profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Lock Accounts After Failed Password Attempts - Define the current authselect
              profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Define the new authselect
              custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Get authselect current
              features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Check if any custom profile
              with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts After Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts After Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Lock Accounts After Failed Password Attempts - Change the PAM file to
              be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Define a fact for control
            already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
            from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/password-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
            be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Lock Accounts After Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom
            profile is used if authselect is present
          block:

          - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
              current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Lock Accounts After Failed Password Attempts - Informative message based
              on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Lock Accounts After Failed Password Attempts - Get authselect current
              profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Lock Accounts After Failed Password Attempts - Define the current authselect
              profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Define the new authselect
              custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Get authselect current
              features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Check if any custom profile
              with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts After Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts After Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts After Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Lock Accounts After Failed Password Attempts - Change the PAM file to
              be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Define a fact for control
            already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
            from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
        deny parameter in PAM files
      block:

      - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
          deny parameter is already enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*deny
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_deny_parameter_is_present

      - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of pam_faillock.so
          preauth deny parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_deny_parameter_is_present.found == 0

      - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of pam_faillock.so
          authfail deny parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
          line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_deny_parameter_is_present.found == 0

      - name: Lock Accounts After Failed Password Attempts - Ensure the desired value
          for pam_faillock.so preauth deny parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(deny)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_deny_parameter_is_present.found > 0

      - name: Lock Accounts After Failed Password Attempts - Ensure the desired value
          for pam_faillock.so authfail deny parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(deny)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_deny_parameter_is_present.found > 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020011
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.6
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Check if system
        relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Remediation where
        authselect tool is present
      block:

      - name: Configure the root Account for Failed Password Attempts - Check integrity
          of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Configure the root Account for Failed Password Attempts - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Configure the root Account for Failed Password Attempts - Get authselect
          current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Configure the root Account for Failed Password Attempts - Ensure "with-faillock"
          feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Configure the root Account for Failed Password Attempts - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Remediation where
        authselect tool is not present
      block:

      - name: Configure the root Account for Failed Password Attempts - Check if pam_faillock.so
          is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
          preauth editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
          authfail editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
          account section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Check the presence
        of /etc/security/faillock.conf file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
        even_deny_root parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*even_deny_root
        line: even_deny_root
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
        even_deny_root parameter not in PAM files
      block:

      - name: Configure the root Account for Failed Password Attempts - Check if /etc/pam.d/system-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Configure the root Account for Failed Password Attempts - Check the proper
          remediation for the system
        block:

        - name: Configure the root Account for Failed Password Attempts - Define the PAM
            file to be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Configure the root Account for Failed Password Attempts - Check if system
            relies on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Configure the root Account for Failed Password Attempts - Ensure authselect
            custom profile is used if authselect is present
          block:

          - name: Configure the root Account for Failed Password Attempts - Check integrity
              of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Configure the root Account for Failed Password Attempts - Informative
              message based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Configure the root Account for Failed Password Attempts - Get authselect
              current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Configure the root Account for Failed Password Attempts - Define the
              current authselect profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Define the
              new authselect custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Get authselect
              current features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Check if any
              custom profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Create an
              authselect custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Configure the root Account for Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Configure the root Account for Failed Password Attempts - Ensure the
              authselect custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Configure the root Account for Failed Password Attempts - Restore the
              authselect features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Configure the root Account for Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Configure the root Account for Failed Password Attempts - Change the
              PAM file to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Configure the root Account for Failed Password Attempts - Define a fact
            for control already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Configure the root Account for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Configure the root Account for Failed Password Attempts - Check if /etc/pam.d/password-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Configure the root Account for Failed Password Attempts - Check the proper
          remediation for the system
        block:

        - name: Configure the root Account for Failed Password Attempts - Define the PAM
            file to be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Configure the root Account for Failed Password Attempts - Check if system
            relies on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Configure the root Account for Failed Password Attempts - Ensure authselect
            custom profile is used if authselect is present
          block:

          - name: Configure the root Account for Failed Password Attempts - Check integrity
              of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Configure the root Account for Failed Password Attempts - Informative
              message based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Configure the root Account for Failed Password Attempts - Get authselect
              current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Configure the root Account for Failed Password Attempts - Define the
              current authselect profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Define the
              new authselect custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Get authselect
              current features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Check if any
              custom profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Configure the root Account for Failed Password Attempts - Create an
              authselect custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Configure the root Account for Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Configure the root Account for Failed Password Attempts - Ensure the
              authselect custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Configure the root Account for Failed Password Attempts - Restore the
              authselect features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Configure the root Account for Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Configure the root Account for Failed Password Attempts - Change the
              PAM file to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Configure the root Account for Failed Password Attempts - Define a fact
            for control already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Configure the root Account for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
        even_deny_root parameter in PAM files
      block:

      - name: Configure the root Account for Failed Password Attempts - Check if pam_faillock.so
          even_deny_root parameter is already enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*even_deny_root
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_even_deny_root_parameter_is_present

      - name: Configure the root Account for Failed Password Attempts - Ensure the inclusion
          of pam_faillock.so preauth even_deny_root parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 even_deny_root
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_even_deny_root_parameter_is_present.found == 0

      - name: Configure the root Account for Failed Password Attempts - Ensure the inclusion
          of pam_faillock.so authfail even_deny_root parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
          line: \1required\3 even_deny_root
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_even_deny_root_parameter_is_present.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020023
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(c)
      - accounts_passwords_pam_faillock_deny_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Check if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Remediation where authselect tool is present
      block:

      - name: Lock Accounts Must Persist - Check integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Lock Accounts Must Persist - Informative message based on the authselect
          integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Lock Accounts Must Persist - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Lock Accounts Must Persist - Ensure "with-faillock" feature is enabled using
          authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Lock Accounts Must Persist - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Remediation where authselect tool is not present
      block:

      - name: Lock Accounts Must Persist - Check if pam_faillock.so is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Lock Accounts Must Persist - Enable pam_faillock.so preauth editing PAM
          files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Lock Accounts Must Persist - Enable pam_faillock.so authfail editing PAM
          files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Lock Accounts Must Persist - Enable pam_faillock.so account section editing
          PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Lock Accounts Must Persist - Check the presence of /etc/security/faillock.conf
        file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure the pam_faillock.so dir parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*dir\s*=
        line: dir = {{ var_accounts_passwords_pam_faillock_dir }}
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure the pam_faillock.so dir parameter not
        in PAM files
      block:

      - name: Lock Accounts Must Persist - Check if /etc/pam.d/system-auth file is present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Lock Accounts Must Persist - Check the proper remediation for the system
        block:

        - name: Lock Accounts Must Persist - Define the PAM file to be edited as a local
            fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Lock Accounts Must Persist - Check if system relies on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Lock Accounts Must Persist - Ensure authselect custom profile is used
            if authselect is present
          block:

          - name: Lock Accounts Must Persist - Check integrity of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Lock Accounts Must Persist - Informative message based on the authselect
              integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Lock Accounts Must Persist - Get authselect current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Lock Accounts Must Persist - Define the current authselect profile as
              a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Lock Accounts Must Persist - Define the new authselect custom profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Lock Accounts Must Persist - Get authselect current features to also
              enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts Must Persist - Check if any custom profile with the same
              name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts Must Persist - Create an authselect custom profile based
              on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Lock Accounts Must Persist - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts Must Persist - Ensure the authselect custom profile is
              selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts Must Persist - Restore the authselect features in the
              custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Lock Accounts Must Persist - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Lock Accounts Must Persist - Change the PAM file to be edited according
              to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Lock Accounts Must Persist - Define a fact for control already filtered
            in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Lock Accounts Must Persist - Ensure the "dir" option from "pam_faillock.so"
            is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bdir\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Lock Accounts Must Persist - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Lock Accounts Must Persist - Check if /etc/pam.d/password-auth file is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Lock Accounts Must Persist - Check the proper remediation for the system
        block:

        - name: Lock Accounts Must Persist - Define the PAM file to be edited as a local
            fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Lock Accounts Must Persist - Check if system relies on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Lock Accounts Must Persist - Ensure authselect custom profile is used
            if authselect is present
          block:

          - name: Lock Accounts Must Persist - Check integrity of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Lock Accounts Must Persist - Informative message based on the authselect
              integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Lock Accounts Must Persist - Get authselect current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Lock Accounts Must Persist - Define the current authselect profile as
              a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Lock Accounts Must Persist - Define the new authselect custom profile
              as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Lock Accounts Must Persist - Get authselect current features to also
              enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts Must Persist - Check if any custom profile with the same
              name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Lock Accounts Must Persist - Create an authselect custom profile based
              on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Lock Accounts Must Persist - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts Must Persist - Ensure the authselect custom profile is
              selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Lock Accounts Must Persist - Restore the authselect features in the
              custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Lock Accounts Must Persist - Ensure authselect changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Lock Accounts Must Persist - Change the PAM file to be edited according
              to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Lock Accounts Must Persist - Define a fact for control already filtered
            in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Lock Accounts Must Persist - Ensure the "dir" option from "pam_faillock.so"
            is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bdir\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Lock Accounts Must Persist - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure the pam_faillock.so dir parameter in PAM
        files
      block:

      - name: Lock Accounts Must Persist - Check if pam_faillock.so dir parameter is already
          enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*dir
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_dir_parameter_is_present

      - name: Lock Accounts Must Persist - Ensure the inclusion of pam_faillock.so preauth
          dir parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 dir={{ var_accounts_passwords_pam_faillock_dir }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_dir_parameter_is_present.found == 0

      - name: Lock Accounts Must Persist - Ensure the inclusion of pam_faillock.so authfail
          dir parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
          line: \1required\3 dir={{ var_accounts_passwords_pam_faillock_dir }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_dir_parameter_is_present.found == 0

      - name: Lock Accounts Must Persist - Ensure the desired value for pam_faillock.so
          preauth dir parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(dir)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_dir }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_dir_parameter_is_present.found > 0

      - name: Lock Accounts Must Persist - Ensure the desired value for pam_faillock.so
          authfail dir parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(dir)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_dir }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_dir_parameter_is_present.found > 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure necessary SELinux packages are installed
      ansible.builtin.package:
        name: '{{ item }}'
        state: present
      with_items:
      - python3-libselinux
      - python3-policycoreutils
      - policycoreutils-python-utils
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Create the tally directory if it does not exist
      ansible.builtin.file:
        path: '{{ var_accounts_passwords_pam_faillock_dir }}'
        state: directory
        setype: faillog_t
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure SELinux file context is permanently set
      ansible.builtin.command:
        cmd: semanage fcontext -a -t faillog_t "{{ var_accounts_passwords_pam_faillock_dir
          }}(/.*)?"
      register: result_accounts_passwords_pam_faillock_dir_semanage
      failed_when: false
      changed_when:
      - result_accounts_passwords_pam_faillock_dir_semanage.rc == 0
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Lock Accounts Must Persist - Ensure SELinux file context is applied
      ansible.builtin.command:
        cmd: restorecon -R "{{ var_accounts_passwords_pam_faillock_dir }}"
      register: result_accounts_passwords_pam_faillock_dir_restorecon
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020016
      - DISA-STIG-RHEL-08-020017
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AC-7(b)
      - NIST-800-53-AC-7.1(ii)
      - accounts_passwords_pam_faillock_dir
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Remediation where authselect
        tool is present
      block:

      - name: Set Interval For Counting Failed Password Attempts - Check integrity of
          authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Set Interval For Counting Failed Password Attempts - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set Interval For Counting Failed Password Attempts - Get authselect current
          features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set Interval For Counting Failed Password Attempts - Ensure "with-faillock"
          feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Set Interval For Counting Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Remediation where authselect
        tool is not present
      block:

      - name: Set Interval For Counting Failed Password Attempts - Check if pam_faillock.so
          is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
          preauth editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
          authfail editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
          account section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Interval For Counting Failed Password Attempts - Check the presence of
        /etc/security/faillock.conf file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Ensure the pam_faillock.so
        fail_interval parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*fail_interval\s*=
        line: fail_interval = {{ var_accounts_passwords_pam_faillock_fail_interval }}
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Ensure the pam_faillock.so
        fail_interval parameter not in PAM files
      block:

      - name: Set Interval For Counting Failed Password Attempts - Check if /etc/pam.d/system-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Set Interval For Counting Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Set Interval For Counting Failed Password Attempts - Define the PAM file
            to be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Set Interval For Counting Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
            custom profile is used if authselect is present
          block:

          - name: Set Interval For Counting Failed Password Attempts - Check integrity
              of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Set Interval For Counting Failed Password Attempts - Informative message
              based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Set Interval For Counting Failed Password Attempts - Get authselect
              current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Set Interval For Counting Failed Password Attempts - Define the current
              authselect profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Define the new
              authselect custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Get authselect
              current features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Check if any custom
              profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Interval For Counting Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Interval For Counting Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Set Interval For Counting Failed Password Attempts - Change the PAM
              file to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Set Interval For Counting Failed Password Attempts - Define a fact for
            control already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Set Interval For Counting Failed Password Attempts - Ensure the "fail_interval"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bfail_interval\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Set Interval For Counting Failed Password Attempts - Check if /etc/pam.d/password-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Set Interval For Counting Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Set Interval For Counting Failed Password Attempts - Define the PAM file
            to be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Set Interval For Counting Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
            custom profile is used if authselect is present
          block:

          - name: Set Interval For Counting Failed Password Attempts - Check integrity
              of authselect current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Set Interval For Counting Failed Password Attempts - Informative message
              based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Set Interval For Counting Failed Password Attempts - Get authselect
              current profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Set Interval For Counting Failed Password Attempts - Define the current
              authselect profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Define the new
              authselect custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Get authselect
              current features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Check if any custom
              profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Set Interval For Counting Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Interval For Counting Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Interval For Counting Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
              changes are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Set Interval For Counting Failed Password Attempts - Change the PAM
              file to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Set Interval For Counting Failed Password Attempts - Define a fact for
            control already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Set Interval For Counting Failed Password Attempts - Ensure the "fail_interval"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bfail_interval\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Set Interval For Counting Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Interval For Counting Failed Password Attempts - Ensure the pam_faillock.so
        fail_interval parameter in PAM files
      block:

      - name: Set Interval For Counting Failed Password Attempts - Check if pam_faillock.so
          fail_interval parameter is already enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*fail_interval
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_fail_interval_parameter_is_present

      - name: Set Interval For Counting Failed Password Attempts - Ensure the inclusion
          of pam_faillock.so preauth fail_interval parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
            }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_fail_interval_parameter_is_present.found == 0

      - name: Set Interval For Counting Failed Password Attempts - Ensure the inclusion
          of pam_faillock.so authfail fail_interval parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
          line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
            }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_fail_interval_parameter_is_present.found == 0

      - name: Set Interval For Counting Failed Password Attempts - Ensure the desired
          value for pam_faillock.so preauth fail_interval parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(fail_interval)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_fail_interval_parameter_is_present.found > 0

      - name: Set Interval For Counting Failed Password Attempts - Ensure the desired
          value for pam_faillock.so authfail fail_interval parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(fail_interval)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_fail_interval_parameter_is_present.found > 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020012
      - DISA-STIG-RHEL-08-020013
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - accounts_passwords_pam_faillock_interval
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Check
        if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Remediation
        where authselect tool is present
      block:

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Check
          integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Informative
          message based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Get
          authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Ensure
          "with-faillock" feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Remediation
        where authselect tool is not present
      block:

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Check
          if pam_faillock.so is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Enable
          pam_faillock.so preauth editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Enable
          pam_faillock.so authfail editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Enable
          pam_faillock.so account section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Check
        the presence of /etc/security/faillock.conf file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Ensure
        the pam_faillock.so silent parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*silent
        line: silent
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Ensure
        the pam_faillock.so silent parameter in PAM files
      block:

      - name: Do Not Show System Messages When Unsuccessful Logon Attempts Occur - Ensure
          the inclusion of pam_faillock.so preauth silent parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth(:?(?!silent).)*)
          line: \1required\3 silent
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020018
      - DISA-STIG-RHEL-08-020019
      - accounts_passwords_pam_faillock_silent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Check if system relies on
        authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
        tool is present
      block:

      - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect
          current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Set Lockout Time for Failed Password Attempts - Informative message based
          on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set Lockout Time for Failed Password Attempts - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set Lockout Time for Failed Password Attempts - Ensure "with-faillock" feature
          is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-faillock
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-faillock")

      - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"pam" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
        tool is not present
      block:

      - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
          is already enabled
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail)
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_is_enabled

      - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so preauth
          editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so preauth
          insertbefore: ^auth.*sufficient.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so authfail
          editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: auth        required      pam_faillock.so authfail
          insertbefore: ^auth.*required.*pam_deny\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0

      - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so account
          section editing PAM files
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          line: account     required      pam_faillock.so
          insertbefore: ^account.*required.*pam_unix\.so.*
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_is_enabled.found == 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Lockout Time for Failed Password Attempts - Check the presence of /etc/security/faillock.conf
        file
      ansible.builtin.stat:
        path: /etc/security/faillock.conf
      register: result_faillock_conf_check
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
        unlock_time parameter in /etc/security/faillock.conf
      ansible.builtin.lineinfile:
        path: /etc/security/faillock.conf
        regexp: ^\s*unlock_time\s*=
        line: unlock_time = {{ var_accounts_passwords_pam_faillock_unlock_time }}
        state: present
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
        unlock_time parameter not in PAM files
      block:

      - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/system-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_file_present

      - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Set Lockout Time for Failed Password Attempts - Define the PAM file to
            be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: Set Lockout Time for Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom
            profile is used if authselect is present
          block:

          - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect
              current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Set Lockout Time for Failed Password Attempts - Informative message
              based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Set Lockout Time for Failed Password Attempts - Get authselect current
              profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Set Lockout Time for Failed Password Attempts - Define the current authselect
              profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Define the new authselect
              custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Get authselect current
              features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Check if any custom
              profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Lockout Time for Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Set Lockout Time for Failed Password Attempts - Change the PAM file
              to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Define a fact for control
            already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists

      - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/password-auth
          file is present
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_file_present

      - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation
          for the system
        block:

        - name: Set Lockout Time for Failed Password Attempts - Define the PAM file to
            be edited as a local fact
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: Set Lockout Time for Failed Password Attempts - Check if system relies
            on authselect tool
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom
            profile is used if authselect is present
          block:

          - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect
              current profile
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            failed_when: false

          - name: Set Lockout Time for Failed Password Attempts - Informative message
              based on the authselect integrity check result
            ansible.builtin.assert:
              that:
              - result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile was
                not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect tool
                is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: Set Lockout Time for Failed Password Attempts - Get authselect current
              profile
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: Set Lockout Time for Failed Password Attempts - Define the current authselect
              profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Define the new authselect
              custom profile as a local fact
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Get authselect current
              features to also enable them in the custom profile
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Check if any custom
              profile with the same name was already created
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - authselect_current_profile is not match("custom/")

          - name: Set Lockout Time for Failed Password Attempts - Create an authselect
              custom profile based on the current profile
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("custom/")
            - not result_authselect_custom_profile_present.stat.exists

          - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect
              custom profile is selected
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: Set Lockout Time for Failed Password Attempts - Restore the authselect
              features in the custom profile
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
              are applied
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: Set Lockout Time for Failed Password Attempts - Change the PAM file
              to be edited according to the custom authselect profile
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
          when:
          - result_authselect_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Define a fact for control
            already filtered in case filters are used
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time"
            option from "pam_faillock.so" is not present in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_file_present.stat.exists
      when:
      - '"pam" in ansible_facts.packages'
      - result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
        unlock_time parameter in PAM files
      block:

      - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
          unlock_time parameter is already enabled in pam files
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: .*auth.*pam_faillock\.so (preauth|authfail).*unlock_time
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_faillock_unlock_time_parameter_is_present

      - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
          pam_faillock.so preauth unlock_time parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
          line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
            }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_unlock_time_parameter_is_present.found == 0

      - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
          pam_faillock.so authfail unlock_time parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
          line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
            }}
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_unlock_time_parameter_is_present.found == 0

      - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
          for pam_faillock.so preauth unlock_time parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(unlock_time)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_unlock_time_parameter_is_present.found > 0

      - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
          for pam_faillock.so authfail unlock_time parameter in auth section
        ansible.builtin.lineinfile:
          path: '{{ item }}'
          backrefs: true
          regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(unlock_time)=[0-9]+(.*)
          line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
          state: present
        loop:
        - /etc/pam.d/system-auth
        - /etc/pam.d/password-auth
        when:
        - result_pam_faillock_unlock_time_parameter_is_present.found > 0
      when:
      - '"pam" in ansible_facts.packages'
      - not result_faillock_conf_check.stat.exists
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020014
      - DISA-STIG-RHEL-08-020015
      - NIST-800-171-3.1.8
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.1.7
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.4
      - accounts_passwords_pam_faillock_unlock_time
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020130
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_dcredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Digit Characters - Ensure
        PAM variable dcredit is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*dcredit
        line: dcredit = {{ var_password_pam_dcredit }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020130
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_dcredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020300
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_dictcheck
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Prevent the Use of Dictionary
        Words - Ensure PAM variable dictcheck is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*dictcheck
        line: dictcheck = {{ var_password_pam_dictcheck }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020300
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_dictcheck
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020170
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(b)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_difok
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Different Characters -
        Ensure PAM variable difok is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*difok
        line: difok = {{ var_password_pam_difok }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020170
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(b)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_difok
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020120
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_lcredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Lowercase Characters -
        Ensure PAM variable lcredit is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*lcredit
        line: lcredit = {{ var_password_pam_lcredit }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020120
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_lcredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020140
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_maxclassrepeat
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Maximum Consecutive Repeating
        Characters from Same Character Class - Ensure PAM variable maxclassrepeat is set
        accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*maxclassrepeat
        line: maxclassrepeat = {{ var_password_pam_maxclassrepeat }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020140
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_maxclassrepeat
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020150
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_maxrepeat
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Password Maximum Consecutive Repeating Characters - Ensure PAM variable
        maxrepeat is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*maxrepeat
        line: maxrepeat = {{ var_password_pam_maxrepeat }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020150
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_maxrepeat
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020160
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_minclass
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Different Categories -
        Ensure PAM variable minclass is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*minclass
        line: minclass = {{ var_password_pam_minclass }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020160
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_minclass
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020230
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_minlen
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Length - Ensure PAM variable
        minlen is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*minlen
        line: minlen = {{ var_password_pam_minlen }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020230
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_minlen
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020280
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_ocredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Special Characters - Ensure
        PAM variable ocredit is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*ocredit
        line: ocredit = {{ var_password_pam_ocredit }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020280
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - accounts_password_pam_ocredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020100
      - accounts_password_pam_pwquality_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM password complexity module is enabled in password-auth - Check
        if /etc/pam.d/password-auth file is present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020100
      - accounts_password_pam_pwquality_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM password complexity module is enabled in password-auth - Check
        the proper remediation for the system
      block:

      - name: Ensure PAM password complexity module is enabled in password-auth - Define
          the PAM file to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Ensure PAM password complexity module is enabled in password-auth - Check
          if system relies on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
          authselect custom profile is used if authselect is present
        block:

        - name: Ensure PAM password complexity module is enabled in password-auth - Check
            integrity of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Ensure PAM password complexity module is enabled in password-auth - Informative
            message based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Ensure PAM password complexity module is enabled in password-auth - Get
            authselect current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Ensure PAM password complexity module is enabled in password-auth - Define
            the current authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Ensure PAM password complexity module is enabled in password-auth - Define
            the new authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in password-auth - Get
            authselect current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in password-auth - Check
            if any custom profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in password-auth - Create
            an authselect custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            the authselect custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM password complexity module is enabled in password-auth - Restore
            the authselect features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Ensure PAM password complexity module is enabled in password-auth - Change
            the PAM file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in password-auth - Define
          a fact for control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: Ensure PAM password complexity module is enabled in password-auth - Check
          if expected PAM module line is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Ensure PAM password complexity module is enabled in password-auth - Include
          or update the PAM module line in {{ pam_file_path }}
        block:

        - name: Ensure PAM password complexity module is enabled in password-auth - Check
            if required PAM module line is present in {{ pam_file_path }} with different
            control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwquality.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            the correct control for the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwquality.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            the required PAM module line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            insertafter: ^account.*required.*pam_permit\.so
            line: password    {{ pam_module_control }}    pam_pwquality.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - |-
          (result_pam_accounts_password_pam_pwquality_password_auth_add is defined and result_pam_accounts_password_pam_pwquality_password_auth_add.changed)
           or (result_pam_accounts_password_pam_pwquality_password_auth_edit is defined and result_pam_accounts_password_pam_pwquality_password_auth_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020100
      - accounts_password_pam_pwquality_password_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020101
      - accounts_password_pam_pwquality_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM password complexity module is enabled in system-auth - Check if
        /etc/pam.d/system-auth file is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020101
      - accounts_password_pam_pwquality_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM password complexity module is enabled in system-auth - Check the
        proper remediation for the system
      block:

      - name: Ensure PAM password complexity module is enabled in system-auth - Define
          the PAM file to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Ensure PAM password complexity module is enabled in system-auth - Check
          if system relies on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          authselect custom profile is used if authselect is present
        block:

        - name: Ensure PAM password complexity module is enabled in system-auth - Check
            integrity of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Ensure PAM password complexity module is enabled in system-auth - Informative
            message based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Ensure PAM password complexity module is enabled in system-auth - Get
            authselect current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Ensure PAM password complexity module is enabled in system-auth - Define
            the current authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Ensure PAM password complexity module is enabled in system-auth - Define
            the new authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in system-auth - Get
            authselect current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in system-auth - Check
            if any custom profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Ensure PAM password complexity module is enabled in system-auth - Create
            an authselect custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            the authselect custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure PAM password complexity module is enabled in system-auth - Restore
            the authselect features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Ensure PAM password complexity module is enabled in system-auth - Change
            the PAM file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in system-auth - Define
          a fact for control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: requisite

      - name: Ensure PAM password complexity module is enabled in system-auth - Check
          if expected PAM module line is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Ensure PAM password complexity module is enabled in system-auth - Include
          or update the PAM module line in {{ pam_file_path }}
        block:

        - name: Ensure PAM password complexity module is enabled in system-auth - Check
            if required PAM module line is present in {{ pam_file_path }} with different
            control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_pwquality.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            the correct control for the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_pwquality.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            the required PAM module line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            insertafter: ^account.*required.*pam_permit\.so
            line: password    {{ pam_module_control }}    pam_pwquality.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
            authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - |-
          (result_pam_accounts_password_pam_pwquality_system_auth_add is defined and result_pam_accounts_password_pam_pwquality_system_auth_add.changed)
           or (result_pam_accounts_password_pam_pwquality_system_auth_edit is defined and result_pam_accounts_password_pam_pwquality_system_auth_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020101
      - accounts_password_pam_pwquality_system_auth
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Define a fact for control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: requisite
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Check if expected PAM module line is present in /etc/pam.d/system-auth
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Include or update the PAM module line in /etc/pam.d/system-auth
      block:

      - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts
          Permitted Per-Session - Check if required PAM module line is present in /etc/pam.d/system-auth
          with different control
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: ^\s*password\s+.*\s+pam_pwquality.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts
          Permitted Per-Session - Ensure the correct control for the required PAM module
          line in /etc/pam.d/system-auth
        ansible.builtin.replace:
          dest: /etc/pam.d/system-auth
          regexp: ^(\s*password\s+).*(\bpam_pwquality.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts
          Permitted Per-Session - Ensure the required PAM module line is included in /etc/pam.d/system-auth
        ansible.builtin.lineinfile:
          dest: /etc/pam.d/system-auth
          insertafter: ^\s*account
          line: password    {{ pam_module_control }}    pam_pwquality.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts
          Permitted Per-Session - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Define a fact for control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: requisite
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Check if the required PAM module option is present in /etc/pam.d/system-auth
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*\sretry\b
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_module_accounts_password_pam_retry_option_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Ensure the "retry" PAM option for "pam_pwquality.so" is included
        in /etc/pam.d/system-auth
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so.*)
        line: \1 retry={{ var_password_pam_retry }}
        state: present
      register: result_pam_accounts_password_pam_retry_add
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_module_accounts_password_pam_retry_option_present.found == 0
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted
        Per-Session - Ensure the required value for "retry" PAM option from "pam_pwquality.so"
        in /etc/pam.d/system-auth
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s+.*)(retry)=[0-9a-zA-Z]+\s*(.*)
        line: \1\2={{ var_password_pam_retry }} \3
      register: result_pam_accounts_password_pam_retry_edit
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_module_accounts_password_pam_retry_option_present.found > 0
      tags:
      - CJIS-5.5.3
      - DISA-STIG-RHEL-08-020104
      - NIST-800-53-AC-7(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(4)
      - accounts_password_pam_retry
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020110
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - accounts_password_pam_ucredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure PAM Enforces Password Requirements - Minimum Uppercase Characters -
        Ensure PAM variable ucredit is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*ucredit
        line: ucredit = {{ var_password_pam_ucredit }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020110
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(4)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - accounts_password_pam_ucredit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010110
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - set_password_hashing_algorithm_logindefs


    - name: Set Password Hashing Algorithm in /etc/login.defs
      lineinfile:
        dest: /etc/login.defs
        regexp: ^#?ENCRYPT_METHOD
        line: ENCRYPT_METHOD {{ var_password_hashing_algorithm }}
        state: present
        create: true
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010110
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - set_password_hashing_algorithm_logindefs


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010160
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_passwordauth


    - name: Set PAM's Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010160
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_passwordauth

    - name: Set PAM's Password Hashing Algorithm - password-auth - Check the proper remediation
        for the system
      block:

      - name: Set PAM's Password Hashing Algorithm - password-auth - Define the PAM file
          to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Set PAM's Password Hashing Algorithm - password-auth - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
          custom profile is used if authselect is present
        block:

        - name: Set PAM's Password Hashing Algorithm - password-auth - Check integrity
            of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Set PAM's Password Hashing Algorithm - password-auth - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
            current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set PAM's Password Hashing Algorithm - password-auth - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Define the new
            authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
            current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - password-auth - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set PAM's Password Hashing Algorithm - password-auth - Change the PAM
            file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Set PAM's Password Hashing Algorithm - password-auth - Define a fact for
          control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Set PAM's Password Hashing Algorithm - password-auth - Check if expected
          PAM module line is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Set PAM's Password Hashing Algorithm - password-auth - Include or update
          the PAM module line in {{ pam_file_path }}
        block:

        - name: Set PAM's Password Hashing Algorithm - password-auth - Check if required
            PAM module line is present in {{ pam_file_path }} with different control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_unix.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the correct
            control for the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the required
            PAM module line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            line: password    {{ pam_module_control }}    pam_unix.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Set PAM's Password Hashing Algorithm - password-auth - Define a fact for
          control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Set PAM's Password Hashing Algorithm - password-auth - Check if the required
          PAM module option is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
            var_password_hashing_algorithm_pam }}\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_set_password_hashing_algorithm_passwordauth_option_present

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the "{{ var_password_hashing_algorithm_pam
          }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
          line: \1 {{ var_password_hashing_algorithm_pam }}
          state: present
        register: result_pam_set_password_hashing_algorithm_passwordauth_add
        when:
        - result_pam_module_set_password_hashing_algorithm_passwordauth_option_present.found
          == 0

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - |-
          (result_pam_set_password_hashing_algorithm_passwordauth_add is defined and result_pam_set_password_hashing_algorithm_passwordauth_add.changed)
           or (result_pam_set_password_hashing_algorithm_passwordauth_edit is defined and result_pam_set_password_hashing_algorithm_passwordauth_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010160
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_passwordauth

    - name: Set PAM's Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
        File is Present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010160
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_passwordauth

    - name: Set PAM's Password Hashing Algorithm - password-auth - Check The Proper Remediation
        For The System
      block:

      - name: Set PAM's Password Hashing Algorithm - password-auth - Define the PAM file
          to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Set PAM's Password Hashing Algorithm - password-auth - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
          custom profile is used if authselect is present
        block:

        - name: Set PAM's Password Hashing Algorithm - password-auth - Check integrity
            of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Set PAM's Password Hashing Algorithm - password-auth - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
            current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set PAM's Password Hashing Algorithm - password-auth - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Define the new
            authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
            current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - password-auth - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - password-auth - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set PAM's Password Hashing Algorithm - password-auth - Change the PAM
            file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure That Only
          the Correct Hashing Algorithm Option For pam_unix.so Is Used in /etc/pam.d/password-auth
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
          replace: \1\2
        when: item != var_password_hashing_algorithm_pam
        loop:
        - sha512
        - yescrypt
        - gost_yescrypt
        - blowfish
        - sha256
        - md5
        - bigcrypt
        register: result_pam_hashing_options_removal

      - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_hashing_options_removal is changed
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010160
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_passwordauth


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010159
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth


    - name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth file
        is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010159
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth

    - name: Set PAM's Password Hashing Algorithm - Check the proper remediation for the
        system
      block:

      - name: Set PAM's Password Hashing Algorithm - Define the PAM file to be edited
          as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Set PAM's Password Hashing Algorithm - Check if system relies on authselect
          tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set PAM's Password Hashing Algorithm - Ensure authselect custom profile
          is used if authselect is present
        block:

        - name: Set PAM's Password Hashing Algorithm - Check integrity of authselect current
            profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Set PAM's Password Hashing Algorithm - Informative message based on the
            authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set PAM's Password Hashing Algorithm - Get authselect current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set PAM's Password Hashing Algorithm - Define the current authselect profile
            as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Define the new authselect custom
            profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Get authselect current features
            to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Check if any custom profile with
            the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Create an authselect custom profile
            based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - Ensure the authselect custom profile
            is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - Restore the authselect features
            in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set PAM's Password Hashing Algorithm - Change the PAM file to be edited
            according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Set PAM's Password Hashing Algorithm - Define a fact for control already
          filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Set PAM's Password Hashing Algorithm - Check if expected PAM module line
          is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Set PAM's Password Hashing Algorithm - Include or update the PAM module
          line in {{ pam_file_path }}
        block:

        - name: Set PAM's Password Hashing Algorithm - Check if required PAM module line
            is present in {{ pam_file_path }} with different control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_unix.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Set PAM's Password Hashing Algorithm - Ensure the correct control for
            the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Set PAM's Password Hashing Algorithm - Ensure the required PAM module
            line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            line: password    {{ pam_module_control }}    pam_unix.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Set PAM's Password Hashing Algorithm - Define a fact for control already
          filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Set PAM's Password Hashing Algorithm - Check if the required PAM module
          option is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
            var_password_hashing_algorithm_pam }}\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_set_password_hashing_algorithm_systemauth_option_present

      - name: Set PAM's Password Hashing Algorithm - Ensure the "{{ var_password_hashing_algorithm_pam
          }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
          line: \1 {{ var_password_hashing_algorithm_pam }}
          state: present
        register: result_pam_set_password_hashing_algorithm_systemauth_add
        when:
        - result_pam_module_set_password_hashing_algorithm_systemauth_option_present.found
          == 0

      - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - |-
          (result_pam_set_password_hashing_algorithm_systemauth_add is defined and result_pam_set_password_hashing_algorithm_systemauth_add.changed)
           or (result_pam_set_password_hashing_algorithm_systemauth_edit is defined and result_pam_set_password_hashing_algorithm_systemauth_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010159
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth

    - name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth File
        is Present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010159
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth

    - name: Set PAM's Password Hashing Algorithm - Check The Proper Remediation For The
        System
      block:

      - name: Set PAM's Password Hashing Algorithm - Define the PAM file to be edited
          as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Set PAM's Password Hashing Algorithm - Check if system relies on authselect
          tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set PAM's Password Hashing Algorithm - Ensure authselect custom profile
          is used if authselect is present
        block:

        - name: Set PAM's Password Hashing Algorithm - Check integrity of authselect current
            profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false

        - name: Set PAM's Password Hashing Algorithm - Informative message based on the
            authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile was
              not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect tool
              is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set PAM's Password Hashing Algorithm - Get authselect current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set PAM's Password Hashing Algorithm - Define the current authselect profile
            as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Define the new authselect custom
            profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Get authselect current features
            to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Check if any custom profile with
            the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")

        - name: Set PAM's Password Hashing Algorithm - Create an authselect custom profile
            based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - Ensure the authselect custom profile
            is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set PAM's Password Hashing Algorithm - Restore the authselect features
            in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set PAM's Password Hashing Algorithm - Change the PAM file to be edited
            according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists

      - name: Set PAM's Password Hashing Algorithm - Ensure That Only the Correct Hashing
          Algorithm Option For pam_unix.so Is Used in /etc/pam.d/system-auth
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
          replace: \1\2
        when: item != var_password_hashing_algorithm_pam
        loop:
        - sha512
        - yescrypt
        - gost_yescrypt
        - blowfish
        - sha256
        - md5
        - bigcrypt
        register: result_pam_hashing_options_removal

      - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_hashing_options_removal is changed
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - CJIS-5.6.2.2
      - DISA-STIG-RHEL-08-010159
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth


    - name: Set Password Hashing Rounds in /etc/login.defs - Ensure SHA_CRYPT_MIN_ROUNDS
        has Minimum Value of 5000
      ansible.builtin.replace:
        path: /etc/login.defs
        regexp: (^\s*SHA_CRYPT_MIN_ROUNDS\s+)(?!(?:[5-9]\d{3,}|\d{5,}))\S*(\s*$)
        replace: \g<1>5000\g<2>
        backup: false
      tags:
      - DISA-STIG-RHEL-08-010130
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - set_password_hashing_min_rounds_logindefs

    - name: Set Password Hashing Rounds in /etc/login.defs - Ensure SHA_CRYPT_MAX_ROUNDS
        has Minimum Value of 5000
      ansible.builtin.replace:
        path: /etc/login.defs
        regexp: (^\s*SHA_CRYPT_MAX_ROUNDS\s+)(?!(?:[5-9]\d{3,}|\d{5,}))\S*(\s*$)
        replace: \g<1>5000\g<2>
        backup: false
      tags:
      - DISA-STIG-RHEL-08-010130
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - set_password_hashing_min_rounds_logindefs


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040180
      - NIST-800-171-3.4.5
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_debug-shell_disabled

    - name: Disable debug-shell SystemD Service - Collect systemd Services Present in
        the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040180
      - NIST-800-171-3.4.5
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_debug-shell_disabled

    - name: Disable debug-shell SystemD Service - Ensure debug-shell.service is Masked
      ansible.builtin.systemd:
        name: debug-shell.service
        state: stopped
        enabled: false
        masked: true
      when:
      - '"kernel" in ansible_facts.packages'
      - service_exists.stdout_lines is search("debug-shell.service", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-040180
      - NIST-800-171-3.4.5
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_debug-shell_disabled

    - name: Unit Socket Exists - debug-shell.socket
      ansible.builtin.command: systemctl -q list-unit-files debug-shell.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040180
      - NIST-800-171-3.4.5
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_debug-shell_disabled

    - name: Disable debug-shell SystemD Service - Disable Socket debug-shell
      ansible.builtin.systemd:
        name: debug-shell.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - '"kernel" in ansible_facts.packages'
      - socket_file_exists.stdout_lines is search("debug-shell.socket", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-040180
      - NIST-800-171-3.4.5
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_debug-shell_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040172
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - disable_ctrlaltdel_burstaction
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed

    - name: Disable Ctrl-Alt-Del Burst Action
      lineinfile:
        dest: /etc/systemd/system.conf
        state: present
        regexp: ^CtrlAltDelBurstAction
        line: CtrlAltDelBurstAction=none
        create: true
      when:
      - '"kernel" in ansible_facts.packages'
      - '"systemd" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040172
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - disable_ctrlaltdel_burstaction
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040170
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_ctrlaltdel_reboot
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed

    - name: Disable Ctrl-Alt-Del Reboot Activation
      systemd:
        name: ctrl-alt-del.target
        force: true
        masked: true
        state: stopped
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040170
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_ctrlaltdel_reboot
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-020035
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - logind_session_timeout
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Set 'StopIdleSessionSec' to '{{ var_logind_session_timeout }}' in the [Login]
        section of '/etc/systemd/logind.conf'
      ini_file:
        path: /etc/systemd/logind.conf
        section: Login
        option: StopIdleSessionSec
        value: '{{ var_logind_session_timeout }}'
        create: true
        mode: 420
      when:
      - '"kernel" in ansible_facts.packages'
      - ( ansible_distribution == 'RedHat' and ansible_distribution_version is version('8.7',
        '>=') and ansible_distribution == 'RedHat' and ansible_distribution_version is
        version('9.0', '!=') ) or ansible_distribution == 'OracleLinux' and ansible_distribution_version
        is version('8.7', '>=')
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-020035
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - logind_session_timeout
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010152
      - NIST-800-171-3.1.1
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - require_emergency_target_auth
      - restrict_strategy

    - name: Require emergency mode password
      lineinfile:
        create: true
        dest: /usr/lib/systemd/system/emergency.service
        regexp: ^#?ExecStart=
        line: ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block
          default"
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010152
      - NIST-800-171-3.1.1
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - require_emergency_target_auth
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010151
      - NIST-800-171-3.1.1
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - require_singleuser_auth
      - restrict_strategy

    - name: Require single user mode password
      lineinfile:
        create: true
        dest: /usr/lib/systemd/system/rescue.service
        regexp: ^#?ExecStart=
        line: ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block
          default"
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010151
      - NIST-800-171-3.1.1
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-2
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - require_singleuser_auth
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010410
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_opensc_installed

    - name: Ensure opensc is installed
      package:
        name: opensc
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010410
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_opensc_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010390
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.3
      - enable_strategy
      - install_smartcard_packages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure openssl-pkcs11 is installed
      package:
        name: openssl-pkcs11
        state: present
      when:
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture != "s390x"
      tags:
      - DISA-STIG-RHEL-08-010390
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.3
      - enable_strategy
      - install_smartcard_packages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020260
      - NIST-800-171-3.5.6
      - NIST-800-53-AC-2(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-4(e)
      - PCI-DSS-Req-8.1.4
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.6
      - account_disable_post_pw_expiration
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Account Expiration Following Inactivity
      lineinfile:
        create: true
        dest: /etc/default/useradd
        regexp: ^INACTIVE
        line: INACTIVE={{ var_account_disable_post_pw_expiration }}
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020260
      - NIST-800-171-3.5.6
      - NIST-800-53-AC-2(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-4(e)
      - PCI-DSS-Req-8.1.4
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.6
      - account_disable_post_pw_expiration
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1
      - DISA-STIG-RHEL-08-020200
      - NIST-800-171-3.5.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.4
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.9
      - accounts_maximum_age_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Password Maximum Age
      lineinfile:
        create: true
        dest: /etc/login.defs
        regexp: ^#?PASS_MAX_DAYS
        line: PASS_MAX_DAYS {{ var_accounts_maximum_age_login_defs }}
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1
      - DISA-STIG-RHEL-08-020200
      - NIST-800-171-3.5.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - PCI-DSS-Req-8.2.4
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.9
      - accounts_maximum_age_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020190
      - NIST-800-171-3.5.8
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_minimum_age_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Password Minimum Age
      lineinfile:
        create: true
        dest: /etc/login.defs
        regexp: ^#?PASS_MIN_DAYS
        line: PASS_MIN_DAYS {{ var_accounts_minimum_age_login_defs }}
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - DISA-STIG-RHEL-08-020190
      - NIST-800-171-3.5.8
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_minimum_age_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1
      - DISA-STIG-RHEL-08-020231
      - NIST-800-171-3.5.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(f)
      - accounts_password_minlen_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set Password Minimum Length in login.defs
      lineinfile:
        dest: /etc/login.defs
        regexp: ^PASS_MIN_LEN *[0-9]*
        state: present
        line: PASS_MIN_LEN        {{ var_accounts_password_minlen_login_defs }}
        create: true
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1
      - DISA-STIG-RHEL-08-020231
      - NIST-800-171-3.5.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(f)
      - accounts_password_minlen_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Collect users with not correct maximum time period between password changes
      ansible.builtin.command:
        cmd: awk -F':' '(/^[^:]+:[^!*]/ && ($5 > {{ var_accounts_maximum_age_login_defs
          }} || $5 == "")) {print $1}' /etc/shadow
      register: user_names
      tags:
      - DISA-STIG-RHEL-08-020210
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.9
      - accounts_password_set_max_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Change the maximum time period between password changes
      ansible.builtin.user:
        user: '{{ item }}'
        password_expire_max: '{{ var_accounts_maximum_age_login_defs }}'
      with_items: '{{ user_names.stdout_lines }}'
      when: user_names.stdout_lines | length > 0
      tags:
      - DISA-STIG-RHEL-08-020210
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.9
      - accounts_password_set_max_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Collect users with not correct minimum time period between password changes
      command: |
        awk -F':' '(/^[^:]+:[^!*]/ && ($4 < {{ var_accounts_minimum_age_login_defs }} || $4 == "")) {print $1}' /etc/shadow
      register: user_names
      tags:
      - DISA-STIG-RHEL-08-020180
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_password_set_min_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Change the minimum time period between password changes
      command: |
        chage -m {{ var_accounts_minimum_age_login_defs }} {{ item }}
      with_items: '{{ user_names.stdout_lines }}'
      when: user_names.stdout_lines | length > 0
      tags:
      - DISA-STIG-RHEL-08-020180
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_password_set_min_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020331
      - DISA-STIG-RHEL-08-020332
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - configure_strategy
      - high_severity
      - low_complexity
      - medium_disruption
      - no_empty_passwords
      - no_reboot_needed

    - name: Prevent Login to Accounts With Empty Password - Check if system relies on
        authselect
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020331
      - DISA-STIG-RHEL-08-020332
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - configure_strategy
      - high_severity
      - low_complexity
      - medium_disruption
      - no_empty_passwords
      - no_reboot_needed

    - name: Prevent Login to Accounts With Empty Password - Remediate using authselect
      block:

      - name: Prevent Login to Accounts With Empty Password - Check integrity of authselect
          current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Prevent Login to Accounts With Empty Password - Informative message based
          on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Prevent Login to Accounts With Empty Password - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Prevent Login to Accounts With Empty Password - Ensure "without-nullok"
          feature is enabled using authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature without-nullok
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("without-nullok")

      - name: Prevent Login to Accounts With Empty Password - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"kernel" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020331
      - DISA-STIG-RHEL-08-020332
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - configure_strategy
      - high_severity
      - low_complexity
      - medium_disruption
      - no_empty_passwords
      - no_reboot_needed

    - name: Prevent Login to Accounts With Empty Password - Remediate directly editing
        PAM files
      ansible.builtin.replace:
        dest: '{{ item }}'
        regexp: nullok
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - '"kernel" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - CJIS-5.5.2
      - DISA-STIG-RHEL-08-020331
      - DISA-STIG-RHEL-08-020332
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(a)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.3
      - PCI-DSSv4-8.3
      - PCI-DSSv4-8.3.1
      - configure_strategy
      - high_severity
      - low_complexity
      - medium_disruption
      - no_empty_passwords
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010121
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.2
      - high_severity
      - low_complexity
      - low_disruption
      - no_empty_passwords_etc_shadow
      - no_reboot_needed
      - restrict_strategy

    - name: Collect users with no password
      command: |
        awk -F: '!$2 {print $1}' /etc/shadow
      register: users_nopasswd
      changed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010121
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.2
      - high_severity
      - low_complexity
      - low_disruption
      - no_empty_passwords_etc_shadow
      - no_reboot_needed
      - restrict_strategy

    - name: Lock users with no password
      command: |
        passwd -l {{ item }}
      with_items: '{{ users_nopasswd.stdout_lines }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - users_nopasswd is not skipped and users_nopasswd.stdout_lines | length > 0
      tags:
      - DISA-STIG-RHEL-08-010121
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.2
      - high_severity
      - low_complexity
      - low_disruption
      - no_empty_passwords_etc_shadow
      - no_reboot_needed
      - restrict_strategy


    - name: Get all /etc/passwd file entries
      getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-040200
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-6(5)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-4(b)
      - PCI-DSS-Req-8.5
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.1
      - accounts_no_uid_except_zero
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy

    - name: Lock the password of the user accounts other than root with uid 0
      command: passwd -l {{ item.key }}
      loop: '{{ getent_passwd | dict2items | rejectattr(''key'', ''search'', ''root'')
        | list }}'
      when: item.value.1  == '0'
      tags:
      - DISA-STIG-RHEL-08-040200
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-6(5)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-4(b)
      - PCI-DSS-Req-8.5
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.1
      - accounts_no_uid_except_zero
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010760
      - accounts_have_homedir_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure new users receive home directories
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/login.defs
          create: true
          regexp: (?i)^\s*CREATE_HOME\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/login.defs
        lineinfile:
          path: /etc/login.defs
          create: true
          regexp: (?i)^\s*CREATE_HOME\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/login.defs
        lineinfile:
          path: /etc/login.defs
          create: true
          regexp: (?i)^\s*CREATE_HOME\s+
          line: CREATE_HOME yes
          state: present
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010760
      - accounts_have_homedir_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020310
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - accounts_logon_fail_delay
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Set accounts logon fail delay
      lineinfile:
        dest: /etc/login.defs
        regexp: ^FAIL_DELAY
        line: FAIL_DELAY {{ var_accounts_fail_delay }}
        create: true
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020310
      - NIST-800-53-AC-7(b)
      - NIST-800-53-CM-6(a)
      - accounts_logon_fail_delay
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.2.2
      - DISA-STIG-RHEL-08-020024
      - NIST-800-53-AC-10
      - NIST-800-53-CM-6(a)
      - accounts_max_concurrent_login_sessions
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Find /etc/security/limits.d files containing maxlogins configuration
      find:
        paths: /etc/security/limits.d
        contains: ^[\s]*\*[\s]+(?:(?:hard)|(?:-))[\s]+maxlogins
        patterns: '*.conf'
      register: maxlogins
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.2.2
      - DISA-STIG-RHEL-08-020024
      - NIST-800-53-AC-10
      - NIST-800-53-CM-6(a)
      - accounts_max_concurrent_login_sessions
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Limit the Number of Concurrent Login Sessions Allowed Per User in files from
        limits.d
      replace:
        dest: '{{ item.path }}'
        regexp: ^#?\*.*maxlogins.*
        replace: '*          hard    maxlogins     {{ var_accounts_max_concurrent_login_sessions
          }}'
      with_items:
      - '{{ maxlogins.files }}'
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.5.2.2
      - DISA-STIG-RHEL-08-020024
      - NIST-800-53-AC-10
      - NIST-800-53-CM-6(a)
      - accounts_max_concurrent_login_sessions
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Limit the Number of Concurrent Login Sessions Allowed Per User
      lineinfile:
        state: present
        dest: /etc/security/limits.conf
        insertbefore: ^# End of file
        regexp: ^#?\*.*maxlogins
        line: '*          hard    maxlogins     {{ var_accounts_max_concurrent_login_sessions
          }}'
        create: true
      when:
      - '"pam" in ansible_facts.packages'
      - maxlogins.matched == 0
      tags:
      - CJIS-5.5.2.2
      - DISA-STIG-RHEL-08-020024
      - NIST-800-53-AC-10
      - NIST-800-53-CM-6(a)
      - accounts_max_concurrent_login_sessions
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: User Initialization Files Must Not Run World-Writable Programs - Initialize
        variables
      set_fact:
        home_user_dirs: []
        world_writable_files: []
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: User Initialization Files Must Not Run World-Writable Programs - Get user's
        home dir list
      ansible.builtin.getent:
        database: passwd
      register: passwd_database
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: User Initialization Files Must Not Run World-Writable Programs - Fill home_user_dirs
      set_fact:
        home_user_dirs: '{{ home_user_dirs + [item.data[4]] }}'
      when: item.data[4] is defined and item.data[2]|int >= 1000 and item.data[2]|int
        != 65534
      with_items: '{{ passwd_database.ansible_facts.getent_passwd | dict2items(key_name=''user'',
        value_name=''data'')}}'
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: User Initialization Files Must Not Run World-Writable Programs - Get world
        writable files
      ansible.builtin.shell: |
        find / -xdev -type f -perm -0002 2> /dev/null
      register: world_writable_files
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: User Initialization Files Must Not Run World-Writable Programs - Find referenced_files
        in init files
      ansible.builtin.find:
        paths: '{{ home_user_dirs }}'
        contains: '{{ item }}'
        hidden: true
        read_whole_file: true
        recurse: true
      with_items: '{{ world_writable_files.stdout_lines }}'
      register: referenced_files
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: User Initialization Files Must Not Run World-Writable Programs - Remove world
        writable permissions
      ansible.builtin.file:
        path: '{{ item.item }}'
        mode: o-w
      when: item.matched > 0
      with_items: '{{ referenced_files.results }}'
      tags:
      - DISA-STIG-RHEL-08-010660
      - accounts_user_dot_no_world_writable_programs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010720
      - accounts_user_interactive_home_directory_defined
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010720
      - accounts_user_interactive_home_directory_defined
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive users have an exclusive home directory defined
      ansible.builtin.user:
        name: '{{ item.key }}'
        home: /home/{{ item.key }}
        create_home: false
      loop: '{{ local_users }}'
      when:
      - item.value[2]|int >= 1000
      - item.value[2]|int != 65534
      - item.value[2]|int < 61184 or item.value[2]|int > 65519
      - not item.value[4] | regex_search('^\/\w*\/\w{1,}')
      tags:
      - DISA-STIG-RHEL-08-010720
      - accounts_user_interactive_home_directory_defined
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010750
      - accounts_user_interactive_home_directory_exists
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010750
      - accounts_user_interactive_home_directory_exists
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive users have a home directory exists
      ansible.builtin.user:
        name: '{{ item.key }}'
        create_home: true
      loop: '{{ local_users }}'
      when:
      - item.value[2]|int >= 1000
      - item.value[2]|int != 65534
      tags:
      - DISA-STIG-RHEL-08-010750
      - accounts_user_interactive_home_directory_exists
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010741
      - accounts_users_home_files_groupownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010741
      - accounts_users_home_files_groupownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Test for existence of home directories to avoid creating them, but only fixing
        ownership
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      - item.value[4] != "/"
      tags:
      - DISA-STIG-RHEL-08-010741
      - accounts_users_home_files_groupownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive local users are the owners of their respective home directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        group: '{{ item.0.value[2] }}'
        recurse: true
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010741
      - accounts_users_home_files_groupownership
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010731
      - accounts_users_home_files_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010731
      - accounts_users_home_files_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Test for existence home directories to avoid creating them.
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      - item.value[4] != "/"
      tags:
      - DISA-STIG-RHEL-08-010731
      - accounts_users_home_files_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive local users have proper permissions on their respective
        home directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        mode: u-s,g-w-s,o=-
        follow: false
        recurse: true
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010731
      - accounts_users_home_files_permissions
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010740
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010740
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Test for existence of home directories to avoid creating them, but only fixing
        group ownership
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      tags:
      - DISA-STIG-RHEL-08-010740
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive local users are the group-owners of their respective home
        directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        group: '{{ item.0.value[2] }}'
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010740
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Gather
        User Info
      ansible.builtin.getent:
        database: passwd
      tags:
      - DISA-STIG-RHEL-08-010770
      - file_permission_user_init_files_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Find
        Init Files
      ansible.builtin.find:
        paths: '{{ item.value[4] }}'
        pattern: '{{ var_user_initialization_files_regex }}'
        hidden: true
        use_regex: true
      with_dict: '{{ ansible_facts.getent_passwd }}'
      when:
      - item.value[4] != "/sbin/nologin"
      - item.key not in ["nobody", "nfsnobody"]
      - item.value[1] | int >= 1000 or item.key == "root"
      register: found_init_files
      tags:
      - DISA-STIG-RHEL-08-010770
      - file_permission_user_init_files_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Fix
        Init Files Permissions
      ansible.builtin.file:
        path: '{{ item.1.path }}'
        mode: u-s,g-wxs,o=
      loop: '{{ q(''ansible.builtin.subelements'', found_init_files.results, ''files'',
        {''skip_missing'': True}) }}'
      tags:
      - DISA-STIG-RHEL-08-010770
      - file_permission_user_init_files_root
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - DISA-STIG-RHEL-08-010730
      - file_permissions_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - DISA-STIG-RHEL-08-010730
      - file_permissions_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Test for existence home directories to avoid creating them.
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      - item.value[4] != "/"
      tags:
      - DISA-STIG-RHEL-08-010730
      - file_permissions_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure interactive local users have proper permissions on their respective
        home directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        mode: u-s,g-w-s,o=-
        follow: false
        recurse: false
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010730
      - file_permissions_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_bashrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Check if umask in /etc/bashrc is already set
      ansible.builtin.lineinfile:
        path: /etc/bashrc
        regexp: ^[^#]*\bumask\s+\d+$
        state: absent
      check_mode: true
      changed_when: false
      register: umask_replace
      when: '"bash" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_bashrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Replace user umask in /etc/bashrc
      ansible.builtin.replace:
        path: /etc/bashrc
        regexp: ^([^#]*\b)umask\s+\d+$
        replace: \g<1>umask {{ var_accounts_user_umask }}
      when:
      - '"bash" in ansible_facts.packages'
      - umask_replace.found > 0
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_bashrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default umask is Appended Correctly
      ansible.builtin.lineinfile:
        create: true
        path: /etc/bashrc
        line: umask {{ var_accounts_user_umask }}
      when:
      - '"bash" in ansible_facts.packages'
      - umask_replace.found == 0
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_bashrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Check if umask in /etc/csh.cshrc is already set
      ansible.builtin.lineinfile:
        path: /etc/csh.cshrc
        regexp: ^(\s*)umask\s+.*
        state: absent
      check_mode: true
      changed_when: false
      register: umask_replace
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_csh_cshrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Replace user umask in /etc/csh.cshrc
      ansible.builtin.replace:
        path: /etc/csh.cshrc
        regexp: ^(\s*)umask(\s+).*
        replace: \g<1>umask\g<2>{{ var_accounts_user_umask }}
      when: umask_replace.found > 0
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_csh_cshrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default umask is Appended Correctly
      ansible.builtin.lineinfile:
        create: true
        path: /etc/csh.cshrc
        line: umask {{ var_accounts_user_umask }}
      when: umask_replace.found == 0
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_csh_cshrc
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020351
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Check if UMASK is already set
      ansible.builtin.lineinfile:
        path: /etc/login.defs
        regexp: ^(\s*)UMASK\s+.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_umask_is_set
      when: '"shadow-utils" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020351
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Replace user UMASK in /etc/login.defs
      ansible.builtin.replace:
        path: /etc/login.defs
        regexp: ^(\s*)UMASK(\s+).*
        replace: \g<1>UMASK\g<2>{{ var_accounts_user_umask }}
      when:
      - '"shadow-utils" in ansible_facts.packages'
      - result_umask_is_set.found > 0
      tags:
      - DISA-STIG-RHEL-08-020351
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default UMASK is Appended Correctly
      ansible.builtin.lineinfile:
        create: true
        path: /etc/login.defs
        line: UMASK {{ var_accounts_user_umask }}
      when:
      - '"shadow-utils" in ansible_facts.packages'
      - result_umask_is_set.found == 0
      tags:
      - DISA-STIG-RHEL-08-020351
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_login_defs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure the Default Umask is Set Correctly in /etc/profile - Locate Profile
        Configuration Files Where umask Is Defined
      ansible.builtin.find:
        paths:
        - /etc/profile.d
        patterns:
        - sh.local
        - '*.sh'
        contains: ^[\s]*umask\s+\d+
      register: result_profile_d_files
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_profile
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default Umask is Set Correctly in /etc/profile - Replace Existing
        umask Value in Files From /etc/profile.d
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: ^(\s*)umask\s+\d+
        replace: \1umask {{ var_accounts_user_umask }}
      loop: '{{ result_profile_d_files.files }}'
      register: result_umask_replaced_profile_d
      when: result_profile_d_files.matched
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_profile
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Is
        Set in /etc/profile if Not Already Set Elsewhere
      ansible.builtin.lineinfile:
        create: true
        mode: 420
        path: /etc/profile
        line: umask {{ var_accounts_user_umask }}
      when: not result_profile_d_files.matched
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_profile
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Value
        For All Existing umask Definition in /etc/profile
      ansible.builtin.replace:
        path: /etc/profile
        regexp: ^(\s*)umask\s+\d+
        replace: \1umask {{ var_accounts_user_umask }}
      register: result_umask_replaced_profile
      tags:
      - DISA-STIG-RHEL-08-020353
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - accounts_umask_etc_profile
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure interactive local users are the owners of their respective initialization
        files
      ansible.builtin.shell:
        cmd: |-
          for dir in $(awk -F':' '{ if ($3 >= 1000 && $3 != 65534) print $6}' /etc/passwd); do
            for file in $(find $dir -maxdepth 1 -type f -name ".*"); do
              if [ "$(basename $file)" != ".bash_history" ]; then
                sed -i 's/^\(\s*umask\s*\)/#\1/g' $file
              fi
            done
          done
      tags:
      - DISA-STIG-RHEL-08-020352
      - accounts_umask_interactive_users
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040004
      - NIST-800-53-SI-16
      - grub2_pti_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy

    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="pti=on"
      when:
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040004
      - NIST-800-53-SI-16
      - grub2_pti_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010422
      - NIST-800-53-CM-7(a)
      - grub2_vsyscall_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="vsyscall=none"
      when:
      - '"grub2-common" in ansible_facts.packages'
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and ansible_architecture == "x86_64" )
      tags:
      - DISA-STIG-RHEL-08-010422
      - NIST-800-53-CM-7(a)
      - grub2_vsyscall_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030680
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_rsyslog-gnutls_installed

    - name: Ensure rsyslog-gnutls is installed
      package:
        name: rsyslog-gnutls
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030680
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_rsyslog-gnutls_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030670
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_rsyslog_installed

    - name: Ensure rsyslog is installed
      package:
        name: rsyslog
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030670
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_rsyslog_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010561
      - NIST-800-53-AU-4(1)
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyslog_enabled

    - name: Enable rsyslog Service - Enable service rsyslog
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable rsyslog Service - Enable Service rsyslog
        ansible.builtin.systemd:
          name: rsyslog
          enabled: true
          state: started
          masked: false
        when:
        - '"rsyslog" in ansible_facts.packages'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010561
      - NIST-800-53-AU-4(1)
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyslog_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030010
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_cron_logging

    - name: Ensure cron Is Logging To Rsyslog - Search if cron configuration exists
      ansible.builtin.command: grep -s "^\s*cron\.\*\s*/var/log/cron$" /etc/rsyslog.conf
        /etc/rsyslog.d/*.conf
      register: cron_log_config_exists
      failed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030010
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_cron_logging

    - name: Ensure cron Is Logging To Rsyslog - Ensure the /etc/rsyslog.d directory exists
      ansible.builtin.file:
        path: /etc/rsyslog.d
        state: directory
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030010
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_cron_logging

    - name: Ensure cron Is Logging To Rsyslog - Add cron log configuration line
      ansible.builtin.lineinfile:
        path: /etc/rsyslog.d/cron.conf
        line: cron.*  /var/log/cron
        create: true
      when:
      - '"kernel" in ansible_facts.packages'
      - cron_log_config_exists.stdout_lines | length == 0
      tags:
      - DISA-STIG-RHEL-08-030010
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_cron_logging

    - name: Ensure cron Is Logging To Rsyslog - Restart the rsyslog service now
      ansible.builtin.service:
        name: rsyslog
        state: restarted
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030010
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_cron_logging


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030720
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_actionsendstreamdriverauthmode

    - name: Ensure Rsyslog Authenticates Off-Loaded Audit Records
      block:

      - name: Deduplicate values from /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: false
          regexp: (?i)^\s*{{ "$ActionSendStreamDriverAuthMode"| regex_escape }}\s
          state: absent

      - name: Check if /etc/rsyslog.d exists
        stat:
          path: /etc/rsyslog.d
        register: _etc_rsyslog_d_exists

      - name: Check if the parameter $ActionSendStreamDriverAuthMode is present in /etc/rsyslog.d
        find:
          paths: /etc/rsyslog.d
          recurse: 'yes'
          follow: 'no'
          contains: ^\s*{{ "$ActionSendStreamDriverAuthMode"| regex_escape }}\s
        register: _etc_rsyslog_d_has_parameter
        when: _etc_rsyslog_d_exists.stat.isdir is defined and _etc_rsyslog_d_exists.stat.isdir

      - name: Remove parameter from files in /etc/rsyslog.d
        lineinfile:
          path: '{{ item.path }}'
          create: false
          regexp: (?i)^\s*{{ "$ActionSendStreamDriverAuthMode"| regex_escape }}\s
          state: absent
        with_items: '{{ _etc_rsyslog_d_has_parameter.files }}'
        when: _etc_rsyslog_d_has_parameter.matched

      - name: Insert correct line to /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: true
          regexp: (?i)^\s*{{ "$ActionSendStreamDriverAuthMode"| regex_escape }}\s
          line: $ActionSendStreamDriverAuthMode x509/name
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030720
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_actionsendstreamdriverauthmode


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030710
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_actionsendstreamdrivermode

    - name: Ensure Rsyslog Encrypts Off-Loaded Audit Records
      block:

      - name: Deduplicate values from /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: false
          regexp: '(?i)^\s*{{ "$ActionSendStreamDriverMode"| regex_escape }} '
          state: absent

      - name: Check if /etc/rsyslog.d exists
        stat:
          path: /etc/rsyslog.d
        register: _etc_rsyslog_d_exists

      - name: Check if the parameter $ActionSendStreamDriverMode is present in /etc/rsyslog.d
        find:
          paths: /etc/rsyslog.d
          recurse: 'yes'
          follow: 'no'
          contains: '^\s*{{ "$ActionSendStreamDriverMode"| regex_escape }} '
        register: _etc_rsyslog_d_has_parameter
        when: _etc_rsyslog_d_exists.stat.isdir is defined and _etc_rsyslog_d_exists.stat.isdir

      - name: Remove parameter from files in /etc/rsyslog.d
        lineinfile:
          path: '{{ item.path }}'
          create: false
          regexp: '(?i)^\s*{{ "$ActionSendStreamDriverMode"| regex_escape }} '
          state: absent
        with_items: '{{ _etc_rsyslog_d_has_parameter.files }}'
        when: _etc_rsyslog_d_has_parameter.matched

      - name: Insert correct line to /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: true
          regexp: '(?i)^\s*{{ "$ActionSendStreamDriverMode"| regex_escape }} '
          line: $ActionSendStreamDriverMode 1
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030710
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_actionsendstreamdrivermode


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030710
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_defaultnetstreamdriver

    - name: Ensure Rsyslog Encrypts Off-Loaded Audit Records
      block:

      - name: Deduplicate values from /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: false
          regexp: '(?i)^\s*{{ "$DefaultNetstreamDriver"| regex_escape }} '
          state: absent

      - name: Check if /etc/rsyslog.d exists
        stat:
          path: /etc/rsyslog.d
        register: _etc_rsyslog_d_exists

      - name: Check if the parameter $DefaultNetstreamDriver is present in /etc/rsyslog.d
        find:
          paths: /etc/rsyslog.d
          recurse: 'yes'
          follow: 'no'
          contains: '^\s*{{ "$DefaultNetstreamDriver"| regex_escape }} '
        register: _etc_rsyslog_d_has_parameter
        when: _etc_rsyslog_d_exists.stat.isdir is defined and _etc_rsyslog_d_exists.stat.isdir

      - name: Remove parameter from files in /etc/rsyslog.d
        lineinfile:
          path: '{{ item.path }}'
          create: false
          regexp: '(?i)^\s*{{ "$DefaultNetstreamDriver"| regex_escape }} '
          state: absent
        with_items: '{{ _etc_rsyslog_d_has_parameter.files }}'
        when: _etc_rsyslog_d_has_parameter.matched

      - name: Insert correct line to /etc/rsyslog.conf
        lineinfile:
          path: /etc/rsyslog.conf
          create: true
          regexp: '(?i)^\s*{{ "$DefaultNetstreamDriver"| regex_escape }} '
          line: $DefaultNetstreamDriver gtls
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030710
      - NIST-800-53-AU-4(1)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_encrypt_offload_defaultnetstreamdriver


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Set facts'
      set_fact:
        conf_files:
        - /etc/rsyslog.conf
        remote_methods:
        - selector: auth.*
          regexp: ^.*auth\.\*.*$
          location: /var/log/secure
        - selector: authpriv.*
          regexp: ^.*authpriv\.\*.*$
          location: /var/log/secure
        - selector: daemon.*
          regexp: ^.*daemon\.\*.*$
          location: /var/log/messages
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Ensure rsyslog.conf
        exists'
      file:
        path: '{{ conf_files.0 }}'
        state: touch
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Gather conf.d files'
      find:
        patterns:
        - '*.conf'
        paths:
        - /etc/rsyslog.d
      register: rsyslogd
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Set conf file(s)'
      set_fact:
        conf_files: '{{ conf_files + [item.path] }}'
      loop: '{{ rsyslogd.files }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - rsyslogd.matched > 0
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Check for existing
        values'
      lineinfile:
        path: '{{ item.1 }}'
        regexp: '{{ item.0.regexp }}'
        state: absent
      check_mode: true
      changed_when: false
      register: remote_method_values
      loop: '{{ remote_methods|product(conf_files)|list }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring

    - name: 'Ensure remote access methods are monitored in Rsyslog: Configure'
      lineinfile:
        path: /etc/rsyslog.conf
        line: '{{ item.item.0.selector }} {{ item.item.0.location }}'
        insertafter: ^.*\/var\/log\/secure.*$
        create: true
      loop: '{{ remote_method_values.results }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - item.found == 0
      tags:
      - DISA-STIG-RHEL-08-010070
      - NIST-800-53-AC-17(1)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - rsyslog_remote_access_monitoring


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030690
      - NIST-800-53-AU-4(1)
      - NIST-800-53-AU-9(2)
      - NIST-800-53-CM-6(a)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - rsyslog_remote_loghost


    - name: Set rsyslog remote loghost
      lineinfile:
        dest: /etc/rsyslog.conf
        regexp: ^\*\.\*
        line: '*.* @@{{ rsyslog_remote_loghost_address }}'
        create: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030690
      - NIST-800-53-AU-4(1)
      - NIST-800-53-AU-9(2)
      - NIST-800-53-CM-6(a)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - rsyslog_remote_loghost


    - name: Ensure System is Not Acting as a Network Sniffer - Gather network interfaces
      ansible.builtin.command:
        cmd: ip -o link show
      register: network_interfaces
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040330
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(2)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MA-3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - low_complexity
      - low_disruption
      - medium_severity
      - network_sniffer_disabled
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure System is Not Acting as a Network Sniffer - Disable promiscuous mode
      ansible.builtin.command:
        cmd: ip link set dev {{ item.split(':')[1] }} multicast off promisc off
      loop: '{{ network_interfaces.stdout_lines }}'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - network_interfaces.stdout_lines is defined and "item.split(':') | length == 3"
      tags:
      - DISA-STIG-RHEL-08-040330
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(2)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MA-3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - low_complexity
      - low_disruption
      - medium_severity
      - network_sniffer_disabled
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040150
      - NIST-800-53-SC-5
      - firewalld-backend
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Setting unquoted shell-style assignment of 'FirewallBackend' to 'nftables'
        in '/etc/firewalld/firewalld.conf'
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/firewalld/firewalld.conf
          create: true
          regexp: (?i)^\s*FirewallBackend=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/firewalld/firewalld.conf
        lineinfile:
          path: /etc/firewalld/firewalld.conf
          create: true
          regexp: (?i)^\s*FirewallBackend=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/firewalld/firewalld.conf
        lineinfile:
          path: /etc/firewalld/firewalld.conf
          create: true
          regexp: (?i)^\s*FirewallBackend=
          line: FirewallBackend=nftables
          state: present
          insertbefore: ^# FirewallBackend
          validate: /usr/bin/bash -n %s
      when:
      - '"kernel" in ansible_facts.packages'
      - '"firewalld" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040150
      - NIST-800-53-SC-5
      - firewalld-backend
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040100
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_firewalld_installed

    - name: Ensure firewalld is installed
      package:
        name: firewalld
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040100
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_firewalld_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040101
      - NIST-800-171-3.1.3
      - NIST-800-171-3.4.7
      - NIST-800-53-AC-4
      - NIST-800-53-CA-3(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_firewalld_enabled

    - name: Verify firewalld Enabled - Enable service firewalld
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Verify firewalld Enabled - Enable Service firewalld
        ansible.builtin.systemd:
          name: firewalld
          enabled: true
          state: started
          masked: false
        when:
        - '"firewalld" in ansible_facts.packages'
      when:
      - '"kernel" in ansible_facts.packages'
      - '"firewalld" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040101
      - NIST-800-171-3.1.3
      - NIST-800-171-3.4.7
      - NIST-800-53-AC-4
      - NIST-800-53-CA-3(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_firewalld_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040261
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_ra

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.all.accept_ra.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040261
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_ra

    - name: Comment out any occurrences of net.ipv6.conf.all.accept_ra from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.all.accept_ra
        replace: '#net.ipv6.conf.all.accept_ra'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040261
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_ra


    - name: Ensure sysctl net.ipv6.conf.all.accept_ra is set
      sysctl:
        name: net.ipv6.conf.all.accept_ra
        value: '{{ sysctl_net_ipv6_conf_all_accept_ra_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040261
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_ra


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040280
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.all.accept_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040280
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_redirects

    - name: Comment out any occurrences of net.ipv6.conf.all.accept_redirects from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.all.accept_redirects
        replace: '#net.ipv6.conf.all.accept_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040280
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_redirects


    - name: Ensure sysctl net.ipv6.conf.all.accept_redirects is set
      sysctl:
        name: net.ipv6.conf.all.accept_redirects
        value: '{{ sysctl_net_ipv6_conf_all_accept_redirects_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040280
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040240
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_source_route

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.all.accept_source_route.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040240
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_source_route

    - name: Comment out any occurrences of net.ipv6.conf.all.accept_source_route from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.all.accept_source_route
        replace: '#net.ipv6.conf.all.accept_source_route'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040240
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_source_route


    - name: Ensure sysctl net.ipv6.conf.all.accept_source_route is set
      sysctl:
        name: net.ipv6.conf.all.accept_source_route
        value: '{{ sysctl_net_ipv6_conf_all_accept_source_route_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040240
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_accept_source_route


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040260
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_forwarding

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.all.forwarding.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040260
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_forwarding

    - name: Comment out any occurrences of net.ipv6.conf.all.forwarding from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.all.forwarding
        replace: '#net.ipv6.conf.all.forwarding'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040260
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_forwarding


    - name: Ensure sysctl net.ipv6.conf.all.forwarding is set
      sysctl:
        name: net.ipv6.conf.all.forwarding
        value: '{{ sysctl_net_ipv6_conf_all_forwarding_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040260
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_all_forwarding


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040262
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_ra

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.default.accept_ra.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040262
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_ra

    - name: Comment out any occurrences of net.ipv6.conf.default.accept_ra from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.default.accept_ra
        replace: '#net.ipv6.conf.default.accept_ra'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040262
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_ra


    - name: Ensure sysctl net.ipv6.conf.default.accept_ra is set
      sysctl:
        name: net.ipv6.conf.default.accept_ra
        value: '{{ sysctl_net_ipv6_conf_default_accept_ra_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040262
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_ra


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040210
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.default.accept_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040210
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_redirects

    - name: Comment out any occurrences of net.ipv6.conf.default.accept_redirects from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.default.accept_redirects
        replace: '#net.ipv6.conf.default.accept_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040210
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_redirects


    - name: Ensure sysctl net.ipv6.conf.default.accept_redirects is set
      sysctl:
        name: net.ipv6.conf.default.accept_redirects
        value: '{{ sysctl_net_ipv6_conf_default_accept_redirects_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040210
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040250
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_source_route

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv6.conf.default.accept_source_route.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040250
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_source_route

    - name: Comment out any occurrences of net.ipv6.conf.default.accept_source_route from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv6.conf.default.accept_source_route
        replace: '#net.ipv6.conf.default.accept_source_route'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040250
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_source_route


    - name: Ensure sysctl net.ipv6.conf.default.accept_source_route is set
      sysctl:
        name: net.ipv6.conf.default.accept_source_route
        value: '{{ sysctl_net_ipv6_conf_default_accept_source_route_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040250
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv6_conf_default_accept_source_route


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040279
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.all.accept_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040279
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_redirects

    - name: Comment out any occurrences of net.ipv4.conf.all.accept_redirects from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.all.accept_redirects
        replace: '#net.ipv4.conf.all.accept_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040279
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_redirects


    - name: Ensure sysctl net.ipv4.conf.all.accept_redirects is set
      sysctl:
        name: net.ipv4.conf.all.accept_redirects
        value: '{{ sysctl_net_ipv4_conf_all_accept_redirects_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040279
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040239
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_source_route

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.all.accept_source_route.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040239
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_source_route

    - name: Comment out any occurrences of net.ipv4.conf.all.accept_source_route from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.all.accept_source_route
        replace: '#net.ipv4.conf.all.accept_source_route'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040239
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_source_route


    - name: Ensure sysctl net.ipv4.conf.all.accept_source_route is set
      sysctl:
        name: net.ipv4.conf.all.accept_source_route
        value: '{{ sysctl_net_ipv4_conf_all_accept_source_route_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040239
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_accept_source_route


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040259
      - NIST-800-53-CM-6(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_forwarding

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.all.forwarding.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040259
      - NIST-800-53-CM-6(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_forwarding

    - name: Comment out any occurrences of net.ipv4.conf.all.forwarding from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.all.forwarding
        replace: '#net.ipv4.conf.all.forwarding'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040259
      - NIST-800-53-CM-6(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_forwarding


    - name: Ensure sysctl net.ipv4.conf.all.forwarding is set
      sysctl:
        name: net.ipv4.conf.all.forwarding
        value: '{{ sysctl_net_ipv4_conf_all_forwarding_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040259
      - NIST-800-53-CM-6(b)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_forwarding


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040285
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_rp_filter

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.all.rp_filter.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040285
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_rp_filter

    - name: Comment out any occurrences of net.ipv4.conf.all.rp_filter from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.all.rp_filter
        replace: '#net.ipv4.conf.all.rp_filter'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040285
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_rp_filter


    - name: Ensure sysctl net.ipv4.conf.all.rp_filter is set
      sysctl:
        name: net.ipv4.conf.all.rp_filter
        value: '{{ sysctl_net_ipv4_conf_all_rp_filter_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040285
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_rp_filter


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040209
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.default.accept_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040209
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_redirects

    - name: Comment out any occurrences of net.ipv4.conf.default.accept_redirects from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.default.accept_redirects
        replace: '#net.ipv4.conf.default.accept_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040209
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_redirects


    - name: Ensure sysctl net.ipv4.conf.default.accept_redirects is set
      sysctl:
        name: net.ipv4.conf.default.accept_redirects
        value: '{{ sysctl_net_ipv4_conf_default_accept_redirects_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040209
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(a)
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.3
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040249
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_source_route

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.default.accept_source_route.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040249
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_source_route

    - name: Comment out any occurrences of net.ipv4.conf.default.accept_source_route from
        config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.default.accept_source_route
        replace: '#net.ipv4.conf.default.accept_source_route'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040249
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_source_route


    - name: Ensure sysctl net.ipv4.conf.default.accept_source_route is set
      sysctl:
        name: net.ipv4.conf.default.accept_source_route
        value: '{{ sysctl_net_ipv4_conf_default_accept_source_route_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040249
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_accept_source_route


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040230
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040230
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

    - name: Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts
        replace: '#net.ipv4.icmp_echo_ignore_broadcasts'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040230
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_icmp_echo_ignore_broadcasts


    - name: Ensure sysctl net.ipv4.icmp_echo_ignore_broadcasts is set
      sysctl:
        name: net.ipv4.icmp_echo_ignore_broadcasts
        value: '{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040230
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - PCI-DSS-Req-1.4.3
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_icmp_echo_ignore_broadcasts


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040220
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_send_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.all.send_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040220
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_send_redirects

    - name: Comment out any occurrences of net.ipv4.conf.all.send_redirects from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.all.send_redirects
        replace: '#net.ipv4.conf.all.send_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040220
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_send_redirects

    - name: Ensure sysctl net.ipv4.conf.all.send_redirects is set to 0
      sysctl:
        name: net.ipv4.conf.all.send_redirects
        value: '0'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040220
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_all_send_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040270
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_send_redirects

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.ipv4.conf.default.send_redirects.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040270
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_send_redirects

    - name: Comment out any occurrences of net.ipv4.conf.default.send_redirects from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.ipv4.conf.default.send_redirects
        replace: '#net.ipv4.conf.default.send_redirects'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040270
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_send_redirects

    - name: Ensure sysctl net.ipv4.conf.default.send_redirects is set to 0
      sysctl:
        name: net.ipv4.conf.default.send_redirects
        value: '0'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1.1
      - DISA-STIG-RHEL-08-040270
      - NIST-800-171-3.1.20
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-5
      - NIST-800-53-SC-7(a)
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.5
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_ipv4_conf_default_send_redirects


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040021
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_atm_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'atm' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/atm.conf
        regexp: install\s+atm
        line: install atm /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040021
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_atm_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040022
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_can_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'can' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/can.conf
        regexp: install\s+can
        line: install can /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040022
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_can_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040026
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_firewire-core_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required

    - name: Ensure kernel module 'firewire-core' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/firewire-core.conf
        regexp: install\s+firewire-core
        line: install firewire-core /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040026
      - NIST-800-53-AC-18
      - disable_strategy
      - kernel_module_firewire-core_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.1
      - DISA-STIG-RHEL-08-040023
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.2
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - kernel_module_sctp_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'sctp' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/sctp.conf
        regexp: install\s+sctp
        line: install sctp /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.10.1
      - DISA-STIG-RHEL-08-040023
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-1.4.2
      - PCI-DSSv4-1.4
      - PCI-DSSv4-1.4.2
      - disable_strategy
      - kernel_module_sctp_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040024
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - kernel_module_tipc_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required

    - name: Ensure kernel module 'tipc' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/tipc.conf
        regexp: install\s+tipc
        line: install tipc /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040024
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - kernel_module_tipc_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.13.1.3
      - DISA-STIG-RHEL-08-040111
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - kernel_module_bluetooth_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'bluetooth' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/bluetooth.conf
        regexp: install\s+bluetooth
        line: install bluetooth /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.13.1.3
      - DISA-STIG-RHEL-08-040111
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - kernel_module_bluetooth_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040110
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces

    - name: Service facts
      ansible.builtin.service_facts: null
      tags:
      - DISA-STIG-RHEL-08-040110
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces

    - name: Ensure NetworkManager is installed
      ansible.builtin.package:
        name: '{{ item }}'
        state: present
      with_items:
      - NetworkManager
      tags:
      - DISA-STIG-RHEL-08-040110
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces

    - name: NetworkManager Deactivate Wireless Network Interfaces
      command: nmcli radio wifi off
      when:
      - '''NetworkManager'' in ansible_facts.packages'
      - ansible_facts.services['NetworkManager.service'].state == 'running'
      tags:
      - DISA-STIG-RHEL-08-040110
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces


    - name: Ensure All World-Writable Directories Are Owned by root User - Define Excluded
        (Non-Local) File Systems and Paths
      ansible.builtin.set_fact:
        excluded_fstypes:
        - afs
        - ceph
        - cifs
        - smb3
        - smbfs
        - sshfs
        - ncpfs
        - ncp
        - nfs
        - nfs4
        - gfs
        - gfs2
        - glusterfs
        - gpfs
        - pvfs2
        - ocfs2
        - lustre
        - davfs
        - fuse.sshfs
        excluded_paths:
        - dev
        - proc
        - run
        - sys
        search_paths: []
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Find Relevant
        Root Directories Ignoring Pre-Defined Excluded Paths
      ansible.builtin.find:
        paths: /
        file_type: directory
        excludes: '{{ excluded_paths }}'
        hidden: true
        recurse: false
      register: result_relevant_root_dirs
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Include Relevant
        Root Directories in a List of Paths to be Searched
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.path]) }}'
      loop: '{{ result_relevant_root_dirs.files }}'
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Increment Search
        Paths List with Local Partitions Mount Points
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.mount]) }}'
      loop: '{{ ansible_mounts }}'
      when:
      - item.fstype not in excluded_fstypes
      - item.mount != '/'
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Increment Search
        Paths List with Local NFS File System Targets
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}'
      loop: '{{ ansible_mounts }}'
      when: item.device is search("localhost:")
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Define Rule
        Specific Facts
      ansible.builtin.set_fact:
        world_writable_dirs: []
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Find All Uncompliant
        Directories in Local File Systems
      ansible.builtin.command:
        cmd: find {{ item }} -xdev -type d -perm -0002 -uid +0
      loop: '{{ search_paths }}'
      changed_when: false
      register: result_found_dirs
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Create List
        of World Writable Directories Not Owned by root
      ansible.builtin.set_fact:
        world_writable_dirs: '{{ world_writable_dirs | union(item.stdout_lines) | list
          }}'
      loop: '{{ result_found_dirs.results }}'
      when: item is not skipped
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Ensure All World-Writable Directories Are Owned by root User - Ensure root
        Ownership on Local World Writable Directories
      ansible.builtin.file:
        path: '{{ item }}'
        owner: root
      loop: '{{ world_writable_dirs }}'
      tags:
      - DISA-STIG-RHEL-08-010700
      - dir_perms_world_writable_root_owned
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define Excluded
        (Non-Local) File Systems and Paths
      ansible.builtin.set_fact:
        excluded_fstypes:
        - afs
        - ceph
        - cifs
        - smb3
        - smbfs
        - sshfs
        - ncpfs
        - ncp
        - nfs
        - nfs4
        - gfs
        - gfs2
        - glusterfs
        - gpfs
        - pvfs2
        - ocfs2
        - lustre
        - davfs
        - fuse.sshfs
        excluded_paths:
        - dev
        - proc
        - run
        - sys
        search_paths: []
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find Relevant
        Root Directories Ignoring Pre-Defined Excluded Paths
      ansible.builtin.find:
        paths: /
        file_type: directory
        excludes: '{{ excluded_paths }}'
        hidden: true
        recurse: false
      register: result_relevant_root_dirs
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Include
        Relevant Root Directories in a List of Paths to be Searched
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.path]) }}'
      loop: '{{ result_relevant_root_dirs.files }}'
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment
        Search Paths List with Local Partitions Mount Points
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.mount]) }}'
      loop: '{{ ansible_mounts }}'
      when:
      - item.fstype not in excluded_fstypes
      - item.mount != '/'
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment
        Search Paths List with Local NFS File System Targets
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}'
      loop: '{{ ansible_mounts }}'
      when: item.device is search("localhost:")
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define Rule
        Specific Facts
      ansible.builtin.set_fact:
        world_writable_dirs: []
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find All
        Uncompliant Directories in Local File Systems
      ansible.builtin.command:
        cmd: find {{ item }} -xdev -type d ( -perm -0002 -a ! -perm -1000 )
      loop: '{{ search_paths }}'
      changed_when: false
      register: result_found_dirs
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Create List
        of World Writable Directories Without Sticky Bit
      ansible.builtin.set_fact:
        world_writable_dirs: '{{ world_writable_dirs | union(item.stdout_lines) | list
          }}'
      loop: '{{ result_found_dirs.results }}'
      when: result_found_dirs is not skipped and item is not skipped
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Verify that All World-Writable Directories Have Sticky Bits Set - Ensure Sticky
        Bit is Set on Local World Writable Directories
      ansible.builtin.file:
        path: '{{ item }}'
        mode: a+t
      loop: '{{ world_writable_dirs }}'
      tags:
      - DISA-STIG-RHEL-08-010190
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - dir_perms_world_writable_sticky_bits
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Test for existence /etc/audit/auditd.conf
      stat:
        path: /etc/audit/auditd.conf
      register: file_exists
      tags:
      - DISA-STIG-RHEL-08-030610
      - NIST-800-53-AU-12(b)
      - configure_strategy
      - file_permissions_etc_audit_auditd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/audit/auditd.conf
      file:
        path: /etc/audit/auditd.conf
        mode: u-xs,g-xws,o-xwrt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030610
      - NIST-800-53-AU-12(b)
      - configure_strategy
      - file_permissions_etc_audit_auditd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Find /etc/audit/rules.d/ file(s)
      command: find -H /etc/audit/rules.d/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt  -type
        f -regextype posix-extended -regex "^.*rules$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-030610
      - NIST-800-53-AU-12(b)
      - configure_strategy
      - file_permissions_etc_audit_rulesd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /etc/audit/rules.d/ file(s)
      file:
        path: '{{ item }}'
        mode: u-xs,g-xws,o-xwrt
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-030610
      - NIST-800-53-AU-12(b)
      - configure_strategy
      - file_permissions_etc_audit_rulesd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010374
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_hardlinks

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*fs.protected_hardlinks.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010374
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_hardlinks

    - name: Comment out any occurrences of fs.protected_hardlinks from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*fs.protected_hardlinks
        replace: '#fs.protected_hardlinks'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010374
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_hardlinks

    - name: Ensure sysctl fs.protected_hardlinks is set to 1
      sysctl:
        name: fs.protected_hardlinks
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010374
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_hardlinks


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010373
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_symlinks

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*fs.protected_symlinks.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010373
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_symlinks

    - name: Comment out any occurrences of fs.protected_symlinks from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*fs.protected_symlinks
        replace: '#fs.protected_symlinks'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010373
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_symlinks

    - name: Ensure sysctl fs.protected_symlinks is set to 1
      sysctl:
        name: fs.protected_symlinks
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010373
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_fs_protected_symlinks


    - name: Ensure group owner on /var/log/
      file:
        path: /var/log/
        state: directory
        group: '0'
      tags:
      - DISA-STIG-RHEL-08-010260
      - configure_strategy
      - file_groupowner_var_log
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Test for existence /var/log/messages
      stat:
        path: /var/log/messages
      register: file_exists
      tags:
      - DISA-STIG-RHEL-08-010230
      - configure_strategy
      - file_groupowner_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner 0 on /var/log/messages
      file:
        path: /var/log/messages
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010230
      - configure_strategy
      - file_groupowner_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Ensure owner on directory /var/log/
      file:
        path: /var/log/
        state: directory
        owner: '0'
      tags:
      - DISA-STIG-RHEL-08-010250
      - configure_strategy
      - file_owner_var_log
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Test for existence /var/log/messages
      stat:
        path: /var/log/messages
      register: file_exists
      tags:
      - DISA-STIG-RHEL-08-010220
      - configure_strategy
      - file_owner_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner 0 on /var/log/messages
      file:
        path: /var/log/messages
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010220
      - configure_strategy
      - file_owner_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Find /var/log/ file(s)
      command: 'find -H /var/log/ -maxdepth 1 -perm /u+s,g+ws,o+wt  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010240
      - configure_strategy
      - file_permissions_var_log
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /var/log/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-ws,o-wt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010240
      - configure_strategy
      - file_permissions_var_log
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Test for existence /var/log/messages
      stat:
        path: /var/log/messages
      register: file_exists
      tags:
      - DISA-STIG-RHEL-08-010210
      - configure_strategy
      - file_permissions_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure permission u-xs,g-xws,o-xwrt on /var/log/messages
      file:
        path: /var/log/messages
        mode: u-xs,g-xws,o-xwrt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - DISA-STIG-RHEL-08-010210
      - configure_strategy
      - file_permissions_var_log_messages
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Ensure group owner on /lib/ recursively
      file:
        path: /lib/
        state: directory
        recurse: true
        group: '0'
      tags:
      - DISA-STIG-RHEL-08-010351
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_group_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner on /lib64/ recursively
      file:
        path: /lib64/
        state: directory
        recurse: true
        group: '0'
      tags:
      - DISA-STIG-RHEL-08-010351
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_group_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner on /usr/lib/ recursively
      file:
        path: /usr/lib/
        state: directory
        recurse: true
        group: '0'
      tags:
      - DISA-STIG-RHEL-08-010351
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_group_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure group owner on /usr/lib64/ recursively
      file:
        path: /usr/lib64/
        state: directory
        recurse: true
        group: '0'
      tags:
      - DISA-STIG-RHEL-08-010351
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_group_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Ensure owner on directory /lib/ recursively
      file:
        path: /lib/
        state: directory
        recurse: true
        owner: '0'
      tags:
      - DISA-STIG-RHEL-08-010341
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on directory /lib64/ recursively
      file:
        path: /lib64/
        state: directory
        recurse: true
        owner: '0'
      tags:
      - DISA-STIG-RHEL-08-010341
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on directory /usr/lib/ recursively
      file:
        path: /usr/lib/
        state: directory
        recurse: true
        owner: '0'
      tags:
      - DISA-STIG-RHEL-08-010341
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on directory /usr/lib64/ recursively
      file:
        path: /usr/lib64/
        state: directory
        recurse: true
        owner: '0'
      tags:
      - DISA-STIG-RHEL-08-010341
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Find /lib/ file(s) recursively
      command: 'find -H /lib/  -perm /g+w,o+w  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /lib/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /lib64/ file(s) recursively
      command: 'find -H /lib64/  -perm /g+w,o+w  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /lib64/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib/ file(s) recursively
      command: 'find -H /usr/lib/  -perm /g+w,o+w  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /usr/lib/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib64/ file(s) recursively
      command: 'find -H /usr/lib64/  -perm /g+w,o+w  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /usr/lib64/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010331
      - NIST-800-53-CM-5
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - dir_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Retrieve the system command files and set their group ownership to root
      command: find -L {{ item }}  ! -group root -type f -exec chgrp root '{}' \;
      with_items:
      - /bin
      - /sbin
      - /usr/bin
      - /usr/sbin
      - /usr/local/bin
      - /usr/local/sbin
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010320
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - file_groupownership_system_commands_dirs
      - medium_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Read list of system executables without root ownership
      command: find /bin/ /usr/bin/ /usr/local/bin/ /sbin/ /usr/sbin/ /usr/local/sbin/
        /usr/libexec \! -user root
      register: no_root_system_executables
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010310
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - file_ownership_binary_dirs
      - medium_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set ownership to root of system executables
      file:
        path: '{{ item }}'
        owner: root
      with_items: '{{ no_root_system_executables.stdout_lines }}'
      when: no_root_system_executables.stdout_lines | length > 0
      tags:
      - DISA-STIG-RHEL-08-010310
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - file_ownership_binary_dirs
      - medium_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Find /lib/ file(s) matching ^.*$ recursively
      command: find -H /lib/  -type f ! -uid 0 -regextype posix-extended -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on /lib/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        owner: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /lib64/ file(s) matching ^.*$ recursively
      command: find -H /lib64/  -type f ! -uid 0 -regextype posix-extended -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on /lib64/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        owner: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib/ file(s) matching ^.*$ recursively
      command: find -H /usr/lib/  -type f ! -uid 0 -regextype posix-extended -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on /usr/lib/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        owner: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib64/ file(s) matching ^.*$ recursively
      command: find -H /usr/lib64/  -type f ! -uid 0 -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Ensure owner on /usr/lib64/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        owner: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010340
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_ownership_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Read list of world and group writable system executables
      ansible.builtin.command: find /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin
        /usr/libexec -perm /022 -type f
      register: world_writable_library_files
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010300
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - file_permissions_binary_dirs
      - medium_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Remove world/group writability of system executables
      ansible.builtin.file:
        path: '{{ item }}'
        mode: go-w
        state: file
      with_items: '{{ world_writable_library_files.stdout_lines }}'
      when: world_writable_library_files.stdout_lines | length > 0
      tags:
      - DISA-STIG-RHEL-08-010300
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - file_permissions_binary_dirs
      - medium_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Find /lib/ file(s) recursively
      command: find -H /lib/  -perm /g+w,o+w  -type f -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /lib/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /lib64/ file(s) recursively
      command: find -H /lib64/  -perm /g+w,o+w  -type f -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /lib64/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib/ file(s) recursively
      command: find -H /usr/lib/  -perm /g+w,o+w  -type f -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /usr/lib/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /usr/lib64/ file(s) recursively
      command: find -H /usr/lib64/  -perm /g+w,o+w  -type f -regextype posix-extended
        -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /usr/lib64/ file(s)
      file:
        path: '{{ item }}'
        mode: g-w,o-w
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010330
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_permissions_library_dirs
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Find /lib/ file(s) matching ^.*$ recursively
      command: find -H /lib/  -type f ! -group 0 -regextype posix-extended -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Ensure group owner on /lib/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        group: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Find /lib64/ file(s) matching ^.*$ recursively
      command: find -H /lib64/  -type f ! -group 0 -regextype posix-extended -regex "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Ensure group owner on /lib64/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        group: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Find /usr/lib/ file(s) matching ^.*$ recursively
      command: find -H /usr/lib/  -type f ! -group 0 -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Ensure group owner on /usr/lib/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        group: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Find /usr/lib64/ file(s) matching ^.*$ recursively
      command: find -H /usr/lib64/  -type f ! -group 0 -regextype posix-extended -regex
        "^.*$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files

    - name: Ensure group owner on /usr/lib64/ file(s) matching ^.*$
      file:
        path: '{{ item }}'
        group: '0'
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010350
      - NIST-800-53-CM-5(6)
      - NIST-800-53-CM-5(6).1
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - root_permissions_syslibrary_files


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040070
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_autofs_disabled

    - name: Disable the Automounter - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-040070
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_autofs_disabled

    - name: Disable the Automounter - Ensure autofs.service is Masked
      ansible.builtin.systemd:
        name: autofs.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages )
      - service_exists.stdout_lines is search("autofs.service", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-040070
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_autofs_disabled

    - name: Unit Socket Exists - autofs.socket
      ansible.builtin.command: systemctl -q list-unit-files autofs.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages
        )
      tags:
      - DISA-STIG-RHEL-08-040070
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_autofs_disabled

    - name: Disable the Automounter - Disable Socket autofs
      ansible.builtin.systemd:
        name: autofs.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages )
      - socket_file_exists.stdout_lines is search("autofs.socket", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-040070
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_autofs_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040025
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - kernel_module_cramfs_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required

    - name: Ensure kernel module 'cramfs' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/cramfs.conf
        regexp: install\s+cramfs
        line: install cramfs /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040025
      - NIST-800-171-3.4.6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - kernel_module_cramfs_disabled
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040080
      - NIST-800-171-3.1.21
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSSv4-3.4
      - PCI-DSSv4-3.4.2
      - disable_strategy
      - kernel_module_usb-storage_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'usb-storage' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/usb-storage.conf
        regexp: install\s+usb-storage
        line: install usb-storage /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040080
      - NIST-800-171-3.1.21
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSSv4-3.4
      - PCI-DSSv4-3.4.2
      - disable_strategy
      - kernel_module_usb-storage_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot/efi: Check information associated to mountpoint'
      command: findmnt --fstab '/boot/efi'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot/efi: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot/efi: If /boot/efi not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /boot/efi
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot/efi: Make sure nosuid option is part of the to
        /boot/efi options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot/efi: Ensure /boot/efi is mounted with nosuid option'
      mount:
        path: /boot/efi
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010572
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_efi_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot: Check information associated to mountpoint'
      command: findmnt --fstab '/boot'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot: If /boot not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /boot
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot: Make sure nosuid option is part of the to /boot
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /boot: Ensure /boot is mounted with nosuid option'
      mount:
        path: /boot
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010571
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_boot_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /dev/shm: Check information associated to mountpoint'
      command: findmnt  '/dev/shm'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /dev/shm: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /dev/shm: If /dev/shm not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /dev/shm
        - tmpfs
        - tmpfs
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - ("" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /dev/shm: Make sure nodev option is part of the to /dev/shm
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined and "nodev" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /dev/shm: Ensure /dev/shm is mounted with nodev option'
      mount:
        path: /dev/shm
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
        length == 0)
      tags:
      - DISA-STIG-RHEL-08-040120
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nodev
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /dev/shm: Check information associated to mountpoint'
      command: findmnt  '/dev/shm'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /dev/shm: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /dev/shm: If /dev/shm not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /dev/shm
        - tmpfs
        - tmpfs
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - ("" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /dev/shm: Make sure noexec option is part of the to
        /dev/shm options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /dev/shm: Ensure /dev/shm is mounted with noexec option'
      mount:
        path: /dev/shm
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
        length == 0)
      tags:
      - DISA-STIG-RHEL-08-040122
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /dev/shm: Check information associated to mountpoint'
      command: findmnt  '/dev/shm'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /dev/shm: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /dev/shm: If /dev/shm not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /dev/shm
        - tmpfs
        - tmpfs
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - ("" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /dev/shm: Make sure nosuid option is part of the to
        /dev/shm options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /dev/shm: Ensure /dev/shm is mounted with nosuid option'
      mount:
        path: /dev/shm
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
        length == 0)
      tags:
      - DISA-STIG-RHEL-08-040121
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_dev_shm_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /home: Check information associated to mountpoint'
      command: findmnt --fstab '/home'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /home: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /home: If /home not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /home
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /home: Make sure noexec option is part of the to /home
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /home: Ensure /home is mounted with noexec option'
      mount:
        path: /home
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010590
      - NIST-800-53-CM-6(b)
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /home: Check information associated to mountpoint'
      command: findmnt --fstab '/home'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/home" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /home: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/home" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /home: If /home not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /home
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/home" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /home: Make sure nosuid option is part of the to /home
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/home" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /home: Ensure /home is mounted with nosuid option'
      mount:
        path: /home
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/home" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-010570
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_home_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010580
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_nonroot_local_partitions
      - no_reboot_needed

    - name: 'Add nodev Option to Non-Root Local Partitions: Refresh facts'
      setup:
        gather_subset: mounts
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010580
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_nonroot_local_partitions
      - no_reboot_needed

    - name: 'Add nodev Option to Non-Root Local Partitions: Ensure non-root local partitions
        are mounted with nodev option'
      mount:
        path: '{{ item.mount }}'
        src: '{{ item.device }}'
        opts: '{{ item.options }},nodev'
        state: mounted
        fstype: '{{ item.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - item.mount is match('/\w')
      - item.options is not search('nodev')
      with_items:
      - '{{ ansible_facts.mounts }}'
      tags:
      - DISA-STIG-RHEL-08-010580
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_nonroot_local_partitions
      - no_reboot_needed

    - name: 'Add nodev Option to Non-Root Local Partitions: Ensure non-root local partitions
        are present with nodev option in /etc/fstab'
      ansible.builtin.replace:
        path: /etc/fstab
        regexp: ^\s*(?!#)(/dev/\S+|UUID=\S+)\s+(/\w\S*)\s+(\S+)\s+(?!nodev)(\S+)(.*)$
        replace: \1 \2 \3 \4,nodev \5
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010580
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_nonroot_local_partitions
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010600
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_removable_partitions
      - no_reboot_needed


    - name: Ensure permission nodev are set on var_removable_partition
      lineinfile:
        path: /etc/fstab
        regexp: ^\s*({{ var_removable_partition }})\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)(.*)$
        backrefs: true
        line: \1 \2 \3 \4,nodev \5
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010600
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nodev_removable_partitions
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010610
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_noexec_removable_partitions
      - no_reboot_needed


    - name: Ensure permission noexec are set on var_removable_partition
      lineinfile:
        path: /etc/fstab
        regexp: ^\s*({{ var_removable_partition }})\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)(.*)$
        backrefs: true
        line: \1 \2 \3 \4,noexec \5
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010610
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_noexec_removable_partitions
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010620
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nosuid_removable_partitions
      - no_reboot_needed


    - name: Ensure permission nosuid are set on var_removable_partition
      lineinfile:
        path: /etc/fstab
        regexp: ^\s*({{ var_removable_partition }})\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)(.*)$
        backrefs: true
        line: \1 \2 \3 \4,nosuid \5
      when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      tags:
      - DISA-STIG-RHEL-08-010620
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_nosuid_removable_partitions
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /tmp: If /tmp not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /tmp: Make sure nodev option is part of the to /tmp options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nodev" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /tmp: Ensure /tmp is mounted with nodev option'
      mount:
        path: /tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040123
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nodev
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /tmp: If /tmp not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /tmp: Make sure noexec option is part of the to /tmp
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /tmp: Ensure /tmp is mounted with noexec option'
      mount:
        path: /tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040125
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /tmp: If /tmp not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /tmp: Make sure nosuid option is part of the to /tmp
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /tmp: Ensure /tmp is mounted with nosuid option'
      mount:
        path: /tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040124
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_tmp_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log/audit: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log/audit'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log/audit: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log/audit: If /var/log/audit not mounted, craft
        mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log/audit
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log/audit: Make sure nodev option is part of the
        to /var/log/audit options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nodev" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log/audit: Ensure /var/log/audit is mounted with
        nodev option'
      mount:
        path: /var/log/audit
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040129
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nodev
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log/audit: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log/audit'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log/audit: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log/audit: If /var/log/audit not mounted, craft
        mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log/audit
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log/audit: Make sure noexec option is part of the
        to /var/log/audit options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log/audit: Ensure /var/log/audit is mounted with
        noexec option'
      mount:
        path: /var/log/audit
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040131
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log/audit: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log/audit'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log/audit: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log/audit: If /var/log/audit not mounted, craft
        mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log/audit
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log/audit: Make sure nosuid option is part of the
        to /var/log/audit options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log/audit: Ensure /var/log/audit is mounted with
        nosuid option'
      mount:
        path: /var/log/audit
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040130
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_audit_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log: If /var/log not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log: Make sure nodev option is part of the to /var/log
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nodev" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/log: Ensure /var/log is mounted with nodev option'
      mount:
        path: /var/log
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040126
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nodev
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log: If /var/log not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log: Make sure noexec option is part of the to
        /var/log options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/log: Ensure /var/log is mounted with noexec option'
      mount:
        path: /var/log
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040128
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log: Check information associated to mountpoint'
      command: findmnt --fstab '/var/log'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log: If /var/log not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/log
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log: Make sure nosuid option is part of the to
        /var/log options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/log: Ensure /var/log is mounted with nosuid option'
      mount:
        path: /var/log
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040127
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_log_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/var/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/tmp: If /var/tmp not mounted, craft mount_info manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/tmp: Make sure nodev option is part of the to /var/tmp
        options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nodev" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed

    - name: 'Add nodev Option to /var/tmp: Ensure /var/tmp is mounted with nodev option'
      mount:
        path: /var/tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040132
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nodev
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/var/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/tmp: If /var/tmp not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/tmp: Make sure noexec option is part of the to
        /var/tmp options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "noexec" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed

    - name: 'Add noexec Option to /var/tmp: Ensure /var/tmp is mounted with noexec option'
      mount:
        path: /var/tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040134
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_noexec
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/tmp: Check information associated to mountpoint'
      command: findmnt --fstab '/var/tmp'
      register: device_name
      failed_when: device_name.rc > 1
      changed_when: false
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/tmp: Create mount_info dictionary variable'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - '{{ device_name.stdout_lines[0].split() | list | lower }}'
      - '{{ device_name.stdout_lines[1].split() | list }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length > 0)
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/tmp: If /var/tmp not mounted, craft mount_info
        manually'
      set_fact:
        mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
      with_together:
      - - target
        - source
        - fstype
        - options
      - - /var/tmp
        - ''
        - ''
        - defaults
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - ("--fstab" | length == 0)
      - device_name.stdout is defined and device_name.stdout_lines is defined
      - (device_name.stdout | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/tmp: Make sure nosuid option is part of the to
        /var/tmp options'
      set_fact:
        mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid''
          }) }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined and "nosuid" not in mount_info.options
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed

    - name: 'Add nosuid Option to /var/tmp: Ensure /var/tmp is mounted with nosuid option'
      mount:
        path: /var/tmp
        src: '{{ mount_info.source }}'
        opts: '{{ mount_info.options }}'
        state: mounted
        fstype: '{{ mount_info.fstype }}'
      when:
      - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
        and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type
        in ["docker", "lxc", "openvz", "podman", "container"] ) )
      - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
      - mount_info is defined
      - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
        | length == 0)
      tags:
      - DISA-STIG-RHEL-08-040133
      - configure_strategy
      - high_disruption
      - low_complexity
      - medium_severity
      - mount_option_var_tmp_nosuid
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040020
      - NIST-800-53-CM-7 (5) (b)
      - NIST-800-53-CM-7 (a)
      - disable_strategy
      - kernel_module_uvcvideo_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required

    - name: Ensure kernel module 'uvcvideo' is disabled
      lineinfile:
        create: true
        dest: /etc/modprobe.d/uvcvideo.conf
        regexp: install\s+uvcvideo
        line: install uvcvideo /bin/false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040020
      - NIST-800-53-CM-7 (5) (b)
      - NIST-800-53-CM-7 (a)
      - disable_strategy
      - kernel_module_uvcvideo_disabled
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010671
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_core_pattern

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.core_pattern.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010671
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_core_pattern

    - name: Comment out any occurrences of kernel.core_pattern from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.core_pattern
        replace: '#kernel.core_pattern'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010671
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_core_pattern

    - name: Ensure sysctl kernel.core_pattern is set to |/bin/false
      sysctl:
        name: kernel.core_pattern
        value: '|/bin/false'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010671
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_core_pattern


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010375
      - NIST-800-171-3.1.5
      - NIST-800-53-SI-11(a)
      - NIST-800-53-SI-11(b)
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_dmesg_restrict

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.dmesg_restrict.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010375
      - NIST-800-171-3.1.5
      - NIST-800-53-SI-11(a)
      - NIST-800-53-SI-11(b)
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_dmesg_restrict

    - name: Comment out any occurrences of kernel.dmesg_restrict from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.dmesg_restrict
        replace: '#kernel.dmesg_restrict'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010375
      - NIST-800-171-3.1.5
      - NIST-800-53-SI-11(a)
      - NIST-800-53-SI-11(b)
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_dmesg_restrict

    - name: Ensure sysctl kernel.dmesg_restrict is set to 1
      sysctl:
        name: kernel.dmesg_restrict
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010375
      - NIST-800-171-3.1.5
      - NIST-800-53-SI-11(a)
      - NIST-800-53-SI-11(b)
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_dmesg_restrict


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010372
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kexec_load_disabled

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.kexec_load_disabled.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010372
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kexec_load_disabled

    - name: Comment out any occurrences of kernel.kexec_load_disabled from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.kexec_load_disabled
        replace: '#kernel.kexec_load_disabled'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010372
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kexec_load_disabled

    - name: Ensure sysctl kernel.kexec_load_disabled is set to 1
      sysctl:
        name: kernel.kexec_load_disabled
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010372
      - NIST-800-53-CM-6
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kexec_load_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010376
      - NIST-800-53-AC-6
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_perf_event_paranoid

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.perf_event_paranoid.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010376
      - NIST-800-53-AC-6
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_perf_event_paranoid

    - name: Comment out any occurrences of kernel.perf_event_paranoid from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.perf_event_paranoid
        replace: '#kernel.perf_event_paranoid'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010376
      - NIST-800-53-AC-6
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_perf_event_paranoid

    - name: Ensure sysctl kernel.perf_event_paranoid is set to 2
      sysctl:
        name: kernel.perf_event_paranoid
        value: '2'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010376
      - NIST-800-53-AC-6
      - disable_strategy
      - low_complexity
      - low_severity
      - medium_disruption
      - reboot_required
      - sysctl_kernel_perf_event_paranoid


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040281
      - NIST-800-53-AC-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_unprivileged_bpf_disabled

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.unprivileged_bpf_disabled.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040281
      - NIST-800-53-AC-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_unprivileged_bpf_disabled

    - name: Comment out any occurrences of kernel.unprivileged_bpf_disabled from config
        files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.unprivileged_bpf_disabled
        replace: '#kernel.unprivileged_bpf_disabled'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040281
      - NIST-800-53-AC-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_unprivileged_bpf_disabled

    - name: Ensure sysctl kernel.unprivileged_bpf_disabled is set to 1
      sysctl:
        name: kernel.unprivileged_bpf_disabled
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040281
      - NIST-800-53-AC-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_unprivileged_bpf_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040282
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_yama_ptrace_scope

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.yama.ptrace_scope.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040282
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_yama_ptrace_scope

    - name: Comment out any occurrences of kernel.yama.ptrace_scope from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.yama.ptrace_scope
        replace: '#kernel.yama.ptrace_scope'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040282
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_yama_ptrace_scope

    - name: Ensure sysctl kernel.yama.ptrace_scope is set to 1
      sysctl:
        name: kernel.yama.ptrace_scope
        value: '1'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040282
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_yama_ptrace_scope


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040286
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_core_bpf_jit_harden

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*net.core.bpf_jit_harden.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040286
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_core_bpf_jit_harden

    - name: Comment out any occurrences of net.core.bpf_jit_harden from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*net.core.bpf_jit_harden
        replace: '#net.core.bpf_jit_harden'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040286
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_core_bpf_jit_harden

    - name: Ensure sysctl net.core.bpf_jit_harden is set to 2
      sysctl:
        name: net.core.bpf_jit_harden
        value: '2'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040286
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_net_core_bpf_jit_harden


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040284
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-39
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_user_max_user_namespaces

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*user.max_user_namespaces.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040284
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-39
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_user_max_user_namespaces

    - name: Comment out any occurrences of user.max_user_namespaces from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*user.max_user_namespaces
        replace: '#user.max_user_namespaces'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040284
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-39
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_user_max_user_namespaces

    - name: Ensure sysctl user.max_user_namespaces is set to 0
      sysctl:
        name: user.max_user_namespaces
        value: '0'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040284
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-39
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_user_max_user_namespaces


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010672
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_systemd-coredump_disabled

    - name: Disable acquiring, saving, and processing core dumps - Collect systemd Socket
        Units Present in the System
      ansible.builtin.command:
        cmd: systemctl -q list-unit-files --type socket
      register: result_systemd_unit_files
      changed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010672
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_systemd-coredump_disabled

    - name: Disable acquiring, saving, and processing core dumps - Ensure systemd-coredump.socket
        is Masked
      ansible.builtin.systemd:
        name: systemd-coredump.socket
        state: stopped
        enabled: false
        masked: true
      when:
      - '"kernel" in ansible_facts.packages'
      - result_systemd_unit_files.stdout_lines is search("systemd-coredump.socket")
      tags:
      - DISA-STIG-RHEL-08-010672
      - NIST-800-53-SC-7(10)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_systemd-coredump_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010675
      - NIST-800-53-CM-6
      - PCI-DSS-Req-3.2
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - coredump_disable_backtraces
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set 'ProcessSizeMax' to '0' in the [Coredump] section of '/etc/systemd/coredump.conf'
      ini_file:
        path: /etc/systemd/coredump.conf
        section: Coredump
        option: ProcessSizeMax
        value: '0'
        create: true
        mode: 420
      when: '"systemd" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010675
      - NIST-800-53-CM-6
      - PCI-DSS-Req-3.2
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - coredump_disable_backtraces
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010674
      - NIST-800-53-CM-6
      - PCI-DSS-Req-3.2
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - coredump_disable_storage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set 'Storage' to 'none' in the [Coredump] section of '/etc/systemd/coredump.conf'
      ini_file:
        path: /etc/systemd/coredump.conf
        section: Coredump
        option: Storage
        value: none
        create: true
        mode: 420
      when: '"systemd" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010674
      - NIST-800-53-CM-6
      - PCI-DSS-Req-3.2
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - coredump_disable_storage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010673
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_users_coredumps
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Disable core dumps with limits
      lineinfile:
        dest: /etc/security/limits.conf
        regexp: ^[^#].*core
        line: '*        hard       core      0'
        create: true
      when: '"pam" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010673
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_users_coredumps
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040283
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - NIST-800-53-SC-30(5)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kptr_restrict

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.kptr_restrict.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040283
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - NIST-800-53-SC-30(5)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kptr_restrict

    - name: Comment out any occurrences of kernel.kptr_restrict from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.kptr_restrict
        replace: '#kernel.kptr_restrict'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040283
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - NIST-800-53-SC-30(5)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kptr_restrict


    - name: Ensure sysctl kernel.kptr_restrict is set
      sysctl:
        name: kernel.kptr_restrict
        value: '{{ sysctl_kernel_kptr_restrict_value }}'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040283
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - NIST-800-53-SC-30(5)
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_kptr_restrict


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010430
      - NIST-800-171-3.1.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - PCI-DSS-Req-2.2.1
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_randomize_va_space

    - name: List /etc/sysctl.d/*.conf files
      find:
        paths:
        - /etc/sysctl.d/
        - /run/sysctl.d/
        - /usr/local/lib/sysctl.d/
        - /usr/lib/sysctl.d/
        contains: ^[\s]*kernel.randomize_va_space.*$
        patterns: '*.conf'
        file_type: any
      register: find_sysctl_d
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010430
      - NIST-800-171-3.1.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - PCI-DSS-Req-2.2.1
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_randomize_va_space

    - name: Comment out any occurrences of kernel.randomize_va_space from config files
      replace:
        path: '{{ item.path }}'
        regexp: ^[\s]*kernel.randomize_va_space
        replace: '#kernel.randomize_va_space'
      loop: '{{ find_sysctl_d.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010430
      - NIST-800-171-3.1.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - PCI-DSS-Req-2.2.1
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_randomize_va_space

    - name: Ensure sysctl kernel.randomize_va_space is set to 2
      sysctl:
        name: kernel.randomize_va_space
        value: '2'
        sysctl_file: /etc/sysctl.conf
        state: present
        reload: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010430
      - NIST-800-171-3.1.7
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-30
      - NIST-800-53-SC-30(2)
      - PCI-DSS-Req-2.2.1
      - PCI-DSSv4-3.3
      - PCI-DSSv4-3.3.1
      - PCI-DSSv4-3.3.1.1
      - disable_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - reboot_required
      - sysctl_kernel_randomize_va_space


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010421
      - NIST-800-53-CM-6(a)
      - grub2_page_poison_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="page_poison=1"
      when:
      - '"kernel" in ansible_facts.packages'
      - '"grub2-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010421
      - NIST-800-53-CM-6(a)
      - grub2_page_poison_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010423
      - NIST-800-53-CM-6(a)
      - grub2_slub_debug_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="slub_debug={{ var_slub_debug_options
        }}"
      when:
      - '"kernel" in ansible_facts.packages'
      - '"grub2-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010423
      - NIST-800-53-CM-6(a)
      - grub2_slub_debug_argument
      - low_disruption
      - medium_complexity
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010171
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_policycoreutils_installed

    - name: Ensure policycoreutils is installed
      package:
        name: policycoreutils
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010171
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - package_policycoreutils_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010450
      - NIST-800-171-3.1.2
      - NIST-800-171-3.7.2
      - NIST-800-53-AC-3
      - NIST-800-53-AC-3(3)(a)
      - NIST-800-53-AU-9
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy
      - selinux_policytype


    - name: Configure SELinux Policy
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUXTYPE=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/selinux/config
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUXTYPE=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/selinux/config
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUXTYPE=
          line: SELINUXTYPE={{ var_selinux_policy_name }}
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010450
      - NIST-800-171-3.1.2
      - NIST-800-171-3.7.2
      - NIST-800-53-AC-3
      - NIST-800-53-AC-3(3)(a)
      - NIST-800-53-AU-9
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy
      - selinux_policytype


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010170
      - NIST-800-171-3.1.2
      - NIST-800-171-3.7.2
      - NIST-800-53-AC-3
      - NIST-800-53-AC-3(3)(a)
      - NIST-800-53-AU-9
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.6
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
      - selinux_state


    - name: Ensure SELinux State is Enforcing
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/selinux/config
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/selinux/config
        lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          line: SELINUX={{ var_selinux_state }}
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010170
      - NIST-800-171-3.1.2
      - NIST-800-171-3.7.2
      - NIST-800-53-AC-3
      - NIST-800-53-AC-3(3)(a)
      - NIST-800-53-AU-9
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2
      - PCI-DSSv4-1.2.6
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
      - selinux_state


    - name: Ensure abrt is removed
      package:
        name: abrt
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040001
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_abrt_removed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010670
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_kdump_disabled

    - name: Disable KDump Kernel Crash Analyzer (kdump) - Collect systemd Services Present
        in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010670
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_kdump_disabled

    - name: Disable KDump Kernel Crash Analyzer (kdump) - Ensure kdump.service is Masked
      ansible.builtin.systemd:
        name: kdump.service
        state: stopped
        enabled: false
        masked: true
      when:
      - '"kernel" in ansible_facts.packages'
      - service_exists.stdout_lines is search("kdump.service", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-010670
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_kdump_disabled

    - name: Unit Socket Exists - kdump.socket
      ansible.builtin.command: systemctl -q list-unit-files kdump.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010670
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_kdump_disabled

    - name: Disable KDump Kernel Crash Analyzer (kdump) - Disable Socket kdump
      ansible.builtin.systemd:
        name: kdump.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - '"kernel" in ansible_facts.packages'
      - socket_file_exists.stdout_lines is search("kdump.socket", multiline=True)
      tags:
      - DISA-STIG-RHEL-08-010670
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_kdump_disabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040135
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(22)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_fapolicyd_installed

    - name: Ensure fapolicyd is installed
      package:
        name: fapolicyd
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040135
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(22)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_fapolicyd_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040136
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(22)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_fapolicyd_enabled

    - name: Enable the File Access Policy Service - Enable service fapolicyd
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable the File Access Policy Service - Enable Service fapolicyd
        ansible.builtin.systemd:
          name: fapolicyd
          enabled: true
          state: started
          masked: false
        when:
        - '"fapolicyd" in ansible_facts.packages'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040136
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(22)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_fapolicyd_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040137
      - NIST-800-53-CM-6 b
      - NIST-800-53-CM-7 (2)
      - NIST-800-53-CM-7 (5) (b)
      - fapolicy_default_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Fapolicy Module to Employ a Deny-all, Permit-by-exception Policy
        to Allow the Execution of Authorized Software Programs. - Ensure a Final Rule
        Denying Everything
      ansible.builtin.copy:
        content: |
          # Red Hat KCS 7003854 (https://access.redhat.com/solutions/7003854)
          deny perm=any all : all
        dest: /etc/fapolicyd/rules.d/99-deny-everything.rules
        owner: root
        group: fapolicyd
        mode: '0644'
      register: result_fapolicyd_final_rule
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040137
      - NIST-800-53-CM-6 b
      - NIST-800-53-CM-7 (2)
      - NIST-800-53-CM-7 (5) (b)
      - fapolicy_default_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Fapolicy Module to Employ a Deny-all, Permit-by-exception Policy
        to Allow the Execution of Authorized Software Programs. - Ensure fapolicyd is
        Not Permissive
      ansible.builtin.lineinfile:
        path: /etc/fapolicyd/fapolicyd.conf
        regexp: ^(permissive\s*=).*$
        line: \1 0
        backrefs: true
      register: result_fapolicyd_enforced
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040137
      - NIST-800-53-CM-6 b
      - NIST-800-53-CM-7 (2)
      - NIST-800-53-CM-7 (5) (b)
      - fapolicy_default_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Fapolicy Module to Employ a Deny-all, Permit-by-exception Policy
        to Allow the Execution of Authorized Software Programs. - Restart fapolicyd If
        Permissive Mode or Final Rule is Changed
      ansible.builtin.service:
        name: fapolicyd
        state: restarted
      when:
      - '"kernel" in ansible_facts.packages'
      - result_fapolicyd_final_rule is changed or result_fapolicyd_enforced is changed
      tags:
      - DISA-STIG-RHEL-08-040137
      - NIST-800-53-CM-6 b
      - NIST-800-53-CM-7 (2)
      - NIST-800-53-CM-7 (5) (b)
      - fapolicy_default_deny
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure vsftpd is removed
      package:
        name: vsftpd
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040360
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-CM-7.1(ii)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(1).1(v)
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - package_vsftpd_removed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010163
      - NIST-800-53-IA-7
      - NIST-800-53-IA-7.1
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_krb5-server_removed

    - name: Ensure krb5-server is removed
      package:
        name: krb5-server
        state: absent
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010163
      - NIST-800-53-IA-7
      - NIST-800-53-IA-7.1
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_krb5-server_removed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010161
      - disable_strategy
      - kerberos_disable_no_keytab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find keytab files
      find:
        paths: /etc/
        patterns: '*.keytab'
      register: keytab_files
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010161
      - disable_strategy
      - kerberos_disable_no_keytab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Remove keytab files
      file:
        path: '{{ item.path }}'
        state: absent
      with_items: '{{ keytab_files.files }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010161
      - disable_strategy
      - kerberos_disable_no_keytab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Ensure mailx is installed
      package:
        name: mailx
        state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-010358
      - NIST-800-53-CM-3(5)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_mailx_installed


    - name: Ensure postfix is installed
      package:
        name: postfix
        state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-030030
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_postfix_installed


    - name: Ensure sendmail is removed
      package:
        name: sendmail
        state: absent
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040002
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_sendmail_removed


    - name: Configure System to Forward All Mail From Postmaster to The Root Account
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/aliases
          create: true
          regexp: (?i)^\s*postmaster\s*:\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/aliases
        lineinfile:
          path: /etc/aliases
          create: true
          regexp: (?i)^\s*postmaster\s*:\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/aliases
        lineinfile:
          path: /etc/aliases
          create: true
          regexp: (?i)^\s*postmaster\s*:\s*
          line: 'postmaster: root'
          state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-030030
      - NIST-800-53-AU-5(a)
      - NIST-800-53-AU-5.1(ii)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - postfix_client_configure_mail_alias_postmaster

    - name: Check if newaliases command is available
      ansible.builtin.stat:
        path: /usr/bin/newaliases
      register: result_newaliases_present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-030030
      - NIST-800-53-AU-5(a)
      - NIST-800-53-AU-5.1(ii)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - postfix_client_configure_mail_alias_postmaster

    - name: Update postfix aliases
      ansible.builtin.command:
        cmd: newaliases
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - result_newaliases_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030030
      - NIST-800-53-AU-5(a)
      - NIST-800-53-AU-5.1(ii)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - postfix_client_configure_mail_alias_postmaster


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040290
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - postfix_prevent_unrestricted_relay
      - restrict_strategy

    - name: Prevent Unrestricted Mail Relaying
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/postfix/main.cf
          create: true
          regexp: (?i)^[ \t]*smtpd_client_restrictions\s*=\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/postfix/main.cf
        lineinfile:
          path: /etc/postfix/main.cf
          create: true
          regexp: (?i)^[ \t]*smtpd_client_restrictions\s*=\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/postfix/main.cf
        lineinfile:
          path: /etc/postfix/main.cf
          create: true
          regexp: (?i)^[ \t]*smtpd_client_restrictions\s*=\s*
          line: smtpd_client_restrictions = permit_mynetworks,reject
          state: present
      when:
      - '"postfix" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - DISA-STIG-RHEL-08-040290
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - postfix_prevent_unrestricted_relay
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010640
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MP-2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nodev_remote_filesystems
      - no_reboot_needed

    - name: Get nfs and nfs4 mount points, that don't have nodev
      command: findmnt --fstab --types nfs,nfs4 -O nonodev -n -P
      register: points_register
      check_mode: false
      changed_when: false
      failed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010640
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MP-2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nodev_remote_filesystems
      - no_reboot_needed

    - name: Add nodev to nfs and nfs4 mount points
      mount:
        path: '{{ item | regex_search(''TARGET="([^"]+)"'',''\1'') | first }}'
        src: '{{ item | regex_search(''SOURCE="([^"]+)"'',''\1'') | first }}'
        fstype: '{{ item | regex_search(''FSTYPE="([^"]+)"'',''\1'') | first }}'
        state: present
        opts: '{{ item | regex_search(''OPTIONS="([^"]+)"'',''\1'') | first }},nodev'
      when:
      - '"kernel" in ansible_facts.packages'
      - (points_register.stdout | length > 0) and '\\x09' not in item
      with_items: '{{ points_register.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010640
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MP-2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nodev_remote_filesystems
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010630
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(10)
      - NIST-800-53-AC-6(8)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_noexec_remote_filesystems
      - no_reboot_needed

    - name: Get nfs and nfs4 mount points, that don't have noexec
      command: findmnt --fstab --types nfs,nfs4 -O nonoexec -n -P
      register: points_register
      check_mode: false
      changed_when: false
      failed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010630
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(10)
      - NIST-800-53-AC-6(8)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_noexec_remote_filesystems
      - no_reboot_needed

    - name: Add noexec to nfs and nfs4 mount points
      mount:
        path: '{{ item | regex_search(''TARGET="([^"]+)"'',''\1'') | first }}'
        src: '{{ item | regex_search(''SOURCE="([^"]+)"'',''\1'') | first }}'
        fstype: '{{ item | regex_search(''FSTYPE="([^"]+)"'',''\1'') | first }}'
        state: present
        opts: '{{ item | regex_search(''OPTIONS="([^"]+)"'',''\1'') | first }},noexec'
      when:
      - '"kernel" in ansible_facts.packages'
      - (points_register.stdout | length > 0) and '\\x09' not in item
      with_items: '{{ points_register.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010630
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(10)
      - NIST-800-53-AC-6(8)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_noexec_remote_filesystems
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010650
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nosuid_remote_filesystems
      - no_reboot_needed

    - name: Get nfs and nfs4 mount points, that don't have nosuid
      command: findmnt --fstab --types nfs,nfs4 -O nonosuid -n -P
      register: points_register
      check_mode: false
      changed_when: false
      failed_when: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010650
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nosuid_remote_filesystems
      - no_reboot_needed

    - name: Add nosuid to nfs and nfs4 mount points
      mount:
        path: '{{ item | regex_search(''TARGET="([^"]+)"'',''\1'') | first }}'
        src: '{{ item | regex_search(''SOURCE="([^"]+)"'',''\1'') | first }}'
        fstype: '{{ item | regex_search(''FSTYPE="([^"]+)"'',''\1'') | first }}'
        state: present
        opts: '{{ item | regex_search(''OPTIONS="([^"]+)"'',''\1'') | first }},nosuid'
      when:
      - '"kernel" in ansible_facts.packages'
      - (points_register.stdout | length > 0) and '\\x09' not in item
      with_items: '{{ points_register.stdout_lines }}'
      tags:
      - DISA-STIG-RHEL-08-010650
      - NIST-800-53-AC-6
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM6(a)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - mount_option_nosuid_remote_filesystems
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-8(1)(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.4.3
      - PCI-DSSv4-10.6
      - PCI-DSSv4-10.6.2
      - chronyd_specify_remote_server
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Detect if chrony is already configured with pools or servers
      find:
        path: /etc
        patterns: chrony.conf
        contains: ^[\s]*(?:server|pool)[\s]+[\w]+
      register: chrony_servers
      when:
      - '"kernel" in ansible_facts.packages'
      - '"chrony" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-8(1)(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.4.3
      - PCI-DSSv4-10.6
      - PCI-DSSv4-10.6.2
      - chronyd_specify_remote_server
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Configure remote time servers
      lineinfile:
        path: /etc/chrony.conf
        line: server {{ item }}
        state: present
        create: true
      loop: '{{ var_multiple_time_servers.split(",") }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - '"chrony" in ansible_facts.packages'
      - chrony_servers.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-8(1)(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.4.3
      - PCI-DSSv4-10.6
      - PCI-DSSv4-10.6.2
      - chronyd_specify_remote_server
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030741
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)
      - chronyd_client_only
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Disable chrony daemon from acting as server
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*port\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/chrony.conf
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*port\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/chrony.conf
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*port\s+
          line: port 0
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030741
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)
      - chronyd_client_only
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030742
      - NIST-800-53-CM-7(1)
      - chronyd_no_chronyc_network
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Disable network management of chrony daemon
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*cmdport\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/chrony.conf
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*cmdport\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/chrony.conf
        lineinfile:
          path: /etc/chrony.conf
          create: true
          regexp: (?i)^\s*cmdport\s+
          line: cmdport 0
          state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030742
      - NIST-800-53-CM-7(1)
      - chronyd_no_chronyc_network
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure Time Service Maxpoll Interval - Check That /etc/ntp.conf Exist
      ansible.builtin.stat:
        path: /etc/ntp.conf
      register: ntp_conf_exist_result
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Update the maxpoll Values in /etc/ntp.conf
      ansible.builtin.replace:
        path: /etc/ntp.conf
        regexp: ^(server.*maxpoll)[ ]+[0-9]+(.*)$
        replace: \1 {{ var_time_service_set_maxpoll }}\2
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - ntp_conf_exist_result.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Set the maxpoll Values in /etc/ntp.conf
      ansible.builtin.replace:
        path: /etc/ntp.conf
        regexp: (^server\s+((?!maxpoll).)*)$
        replace: \1 maxpoll {{ var_time_service_set_maxpoll }}\n
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - ntp_conf_exist_result.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Check That /etc/chrony.conf Exist
      ansible.builtin.stat:
        path: /etc/chrony.conf
      register: chrony_conf_exist_result
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Update the maxpoll Values in /etc/chrony.conf
      ansible.builtin.replace:
        path: /etc/chrony.conf
        regexp: ^((?:server|pool|peer).*maxpoll)[ ]+[0-9]+(.*)$
        replace: \1 {{ var_time_service_set_maxpoll }}\2
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - chrony_conf_exist_result.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Set the maxpoll Values in /etc/chrony.conf
      ansible.builtin.replace:
        path: /etc/chrony.conf
        regexp: (^(?:server|pool|peer)\s+((?!maxpoll).)*)$
        replace: \1 maxpoll {{ var_time_service_set_maxpoll }}\n
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - chrony_conf_exist_result.stat.exists
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Get Conf Files from /etc/chrony.d/
      ansible.builtin.find:
        path: /etc/chrony.d/
        patterns: '*.conf'
        file_type: file
      register: chrony_d_conf_files
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Update the maxpoll Values in /etc/chrony.d/
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: ^((?:server|pool|peer).*maxpoll)[ ]+[0-9,-]+(.*)$
        replace: \1 {{ var_time_service_set_maxpoll }}\2
      loop: '{{ chrony_d_conf_files.files }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - chrony_d_conf_files.matched
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Configure Time Service Maxpoll Interval - Set the maxpoll Values in /etc/chrony.d/
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: (^(?:server|pool|peer)\s+((?!maxpoll).)*)$
        replace: \1 maxpoll {{ var_time_service_set_maxpoll }}\n
      loop: '{{ chrony_d_conf_files.files }}'
      when:
      - '"kernel" in ansible_facts.packages'
      - ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
      - chrony_d_conf_files.matched
      tags:
      - DISA-STIG-RHEL-08-030740
      - NIST-800-53-AU-12(1)
      - NIST-800-53-AU-8(1)(b)
      - NIST-800-53-CM-6(a)
      - chronyd_or_ntpd_set_maxpoll
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Ensure rsh-server is removed
      package:
        name: rsh-server
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040010
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-IA-5(1)(c)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - package_rsh-server_removed


    - name: Remove Host-Based Authentication Files - Define Excluded (Non-Local) File
        Systems and Paths
      ansible.builtin.set_fact:
        excluded_fstypes:
        - afs
        - ceph
        - cifs
        - smb3
        - smbfs
        - sshfs
        - ncpfs
        - ncp
        - nfs
        - nfs4
        - gfs
        - gfs2
        - glusterfs
        - gpfs
        - pvfs2
        - ocfs2
        - lustre
        - davfs
        - fuse.sshfs
        excluded_paths:
        - dev
        - proc
        - run
        - sys
        search_paths: []
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Find Relevant Root Directories Ignoring
        Pre-Defined Excluded Paths
      ansible.builtin.find:
        paths: /
        file_type: directory
        excludes: '{{ excluded_paths }}'
        hidden: true
        recurse: false
      register: result_relevant_root_dirs
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Include Relevant Root Directories
        in a List of Paths to be Searched
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.path]) }}'
      loop: '{{ result_relevant_root_dirs.files }}'
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Increment Search Paths List with
        Local Partitions Mount Points
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.mount]) }}'
      loop: '{{ ansible_mounts }}'
      when:
      - item.fstype not in excluded_fstypes
      - item.mount != '/'
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Increment Search Paths List with
        Local NFS File System Targets
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}'
      loop: '{{ ansible_mounts }}'
      when: item.device is search("localhost:")
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Define Rule Specific Facts
      ansible.builtin.set_fact:
        shosts_equiv_files:
        - /shosts.equiv
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Find All shosts.equiv Files in Local
        File Systems
      ansible.builtin.command:
        cmd: find {{ item }} -xdev -type f -name "shosts.equiv"
      loop: '{{ search_paths }}'
      changed_when: false
      register: result_found_shosts_equiv_files
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Create List of shosts.equiv Files
        Present in Local File Systems
      ansible.builtin.set_fact:
        shosts_equiv_files: '{{ shosts_equiv_files | union(item.stdout_lines) | list }}'
      loop: '{{ result_found_shosts_equiv_files.results }}'
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy

    - name: Remove Host-Based Authentication Files - Ensure No shosts.equiv Files Are
        Present in the System
      ansible.builtin.file:
        path: '{{ item }}'
        state: absent
      loop: '{{ shosts_equiv_files }}'
      tags:
      - DISA-STIG-RHEL-08-010460
      - high_severity
      - low_complexity
      - low_disruption
      - no_host_based_files
      - no_reboot_needed
      - restrict_strategy


    - name: Remove User Host-Based Authentication Files - Define Excluded (Non-Local)
        File Systems and Paths
      ansible.builtin.set_fact:
        excluded_fstypes:
        - afs
        - ceph
        - cifs
        - smb3
        - smbfs
        - sshfs
        - ncpfs
        - ncp
        - nfs
        - nfs4
        - gfs
        - gfs2
        - glusterfs
        - gpfs
        - pvfs2
        - ocfs2
        - lustre
        - davfs
        - fuse.sshfs
        excluded_paths:
        - dev
        - proc
        - run
        - sys
        search_paths: []
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Find Relevant Root Directories
        Ignoring Pre-Defined Excluded Paths
      ansible.builtin.find:
        paths: /
        file_type: directory
        excludes: '{{ excluded_paths }}'
        hidden: true
        recurse: false
      register: result_relevant_root_dirs
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Include Relevant Root Directories
        in a List of Paths to be Searched
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.path]) }}'
      loop: '{{ result_relevant_root_dirs.files }}'
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Increment Search Paths List
        with Local Partitions Mount Points
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.mount]) }}'
      loop: '{{ ansible_mounts }}'
      when:
      - item.fstype not in excluded_fstypes
      - item.mount != '/'
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Increment Search Paths List
        with Local NFS File System Targets
      ansible.builtin.set_fact:
        search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}'
      loop: '{{ ansible_mounts }}'
      when: item.device is search("localhost:")
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Define Rule Specific Facts
      ansible.builtin.set_fact:
        user_shosts_files:
        - /.shosts
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Find All .shosts Files in Local
        File Systems
      ansible.builtin.command:
        cmd: find {{ item }} -xdev -type f -name ".shosts"
      loop: '{{ search_paths }}'
      changed_when: false
      register: result_found_shosts_files
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Create List of .shosts Files
        Present in Local File Systems
      ansible.builtin.set_fact:
        user_shosts_files: '{{ user_shosts_files | union(item.stdout_lines) | list }}'
      loop: '{{ result_found_shosts_files.results }}'
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy

    - name: Remove User Host-Based Authentication Files - Ensure No .shosts Files Are
        Present in the System
      ansible.builtin.file:
        path: '{{ item }}'
        state: absent
      loop: '{{ user_shosts_files }}'
      tags:
      - DISA-STIG-RHEL-08-010470
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - no_user_host_based_files
      - restrict_strategy


    - name: Ensure telnet-server is removed
      package:
        name: telnet-server
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040000
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.2
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - package_telnet-server_removed


    - name: Ensure tftp-server is removed
      package:
        name: tftp-server
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040190
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - package_tftp-server_removed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040350
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-7(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - tftpd_uses_secure_mode


    - name: Find out if the file exists and contains the line configuring server arguments
      find:
        path: /etc/xinetd.d
        patterns: tftp
        contains: ^[\s]+server_args.*$
      register: tftpd_secure_config_line
      when: '"tftp-server" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040350
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-7(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - tftpd_uses_secure_mode

    - name: Ensure that TFTP server is configured to start with secure directory
      lineinfile:
        path: /etc/xinetd.d/tftp
        regexp: ^[\s]*(server_args[\s]+=[\s]+.*?)(-s[\s]+[/\.\w]+)*(.*)$
        line: \1 -s {{ var_tftpd_secure_directory }} \3
        state: present
        backrefs: true
      when:
      - '"tftp-server" in ansible_facts.packages'
      - tftpd_secure_config_line is defined and tftpd_secure_config_line.matched > 0
      tags:
      - DISA-STIG-RHEL-08-040350
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-7(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - tftpd_uses_secure_mode

    - name: Insert correct config line to start TFTP server with secure directory
      lineinfile:
        path: /etc/xinetd.d/tftp
        line: server_args = -s {{ var_tftpd_secure_directory }}
        state: present
        create: true
      when:
      - '"tftp-server" in ansible_facts.packages'
      - tftpd_secure_config_line is defined and tftpd_secure_config_line.matched == 0
      tags:
      - DISA-STIG-RHEL-08-040350
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-7(a)
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - tftpd_uses_secure_mode


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010471
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rngd_enabled

    - name: Enable the Hardware RNG Entropy Gatherer Service - Enable service rngd
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable the Hardware RNG Entropy Gatherer Service - Enable Service rngd
        ansible.builtin.systemd:
          name: rngd
          enabled: true
          state: started
          masked: false
        when:
        - '"rng-tools" in ansible_facts.packages'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010471
      - enable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rngd_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040159
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_openssh-server_installed

    - name: Ensure openssh-server is installed
      package:
        name: openssh-server
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040159
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_openssh-server_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040160
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.8
      - NIST-800-171-3.5.4
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-8
      - NIST-800-53-SC-8(1)
      - NIST-800-53-SC-8(2)
      - NIST-800-53-SC-8(3)
      - NIST-800-53-SC-8(4)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_sshd_enabled

    - name: Enable the OpenSSH Service - Enable service sshd
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable the OpenSSH Service - Enable Service sshd
        ansible.builtin.systemd:
          name: sshd
          enabled: true
          state: started
          masked: false
        when:
        - '"openssh-server" in ansible_facts.packages'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040160
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.8
      - NIST-800-171-3.5.4
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-8
      - NIST-800-53-SC-8(1)
      - NIST-800-53-SC-8(2)
      - NIST-800-53-SC-8(3)
      - NIST-800-53-SC-8(4)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_sshd_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010490
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_private_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find root:root-owned keys
      ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$"
        -type f -group root -perm /u+xs,g+xwrs,o+xwrt
      register: root_owned_keys
      changed_when: false
      failed_when: false
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010490
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_private_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for root:root-owned keys
      ansible.builtin.file:
        path: '{{ item }}'
        mode: u-xs,g-xwrs,o-xwrt
        state: file
      with_items:
      - '{{ root_owned_keys.stdout_lines }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010490
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_private_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find root:ssh_keys-owned keys
      ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$"
        -type f -group ssh_keys -perm /u+xs,g+xws,o+xwrt
      register: dedicated_group_owned_keys
      changed_when: false
      failed_when: false
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010490
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_private_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for root:ssh_keys-owned keys
      ansible.builtin.file:
        path: '{{ item }}'
        mode: u-xs,g-xws,o-xwrt
        state: file
      with_items:
      - '{{ dedicated_group_owned_keys.stdout_lines }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010490
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_private_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010480
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_pub_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Find /etc/ssh/ file(s)
      command: find -H /etc/ssh/ -maxdepth 1 -perm /u+xs,g+xws,o+xwt  -type f -regextype
        posix-extended -regex "^.*\.pub$"
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010480
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_pub_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set permissions for /etc/ssh/ file(s)
      file:
        path: '{{ item }}'
        mode: u-xs,g-xws,o-xwt
        state: file
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010480
      - NIST-800-171-3.1.13
      - NIST-800-171-3.13.10
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_sshd_pub_key
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010200
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_keepalive


    - name: Set SSH Client Alive Count Max
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
          line: ClientAliveCountMax {{ var_sshd_set_keepalive }}
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010200
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_keepalive


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010201
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_idle_timeout


    - name: Set SSH Client Alive Interval
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveInterval\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveInterval\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*ClientAliveInterval\s+
          line: ClientAliveInterval {{ sshd_idle_timeout_value }}
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010201
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSS-Req-8.1.8
      - PCI-DSSv4-8.2
      - PCI-DSSv4-8.2.8
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_idle_timeout


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-020330
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_empty_passwords

    - name: Disable SSH Access via Empty Passwords
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
          line: PermitEmptyPasswords no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-020330
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_empty_passwords


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010522
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_gssapi_auth

    - name: Disable GSSAPI Authentication
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
          line: GSSAPIAuthentication no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010522
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_gssapi_auth


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010521
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_kerb_auth

    - name: Disable Kerberos Authentication
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*KerberosAuthentication\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*KerberosAuthentication\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*KerberosAuthentication\s+
          line: KerberosAuthentication no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010521
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_kerb_auth


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010550
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(2)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-2(5)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_root_login

    - name: Disable SSH Root Login
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitRootLogin\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitRootLogin\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitRootLogin\s+
          line: PermitRootLogin no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010550
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(2)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-2(5)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_root_login


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010520
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_user_known_hosts

    - name: Disable SSH Support for User Known Hosts
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*IgnoreUserKnownHosts\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*IgnoreUserKnownHosts\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*IgnoreUserKnownHosts\s+
          line: IgnoreUserKnownHosts yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010520
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_user_known_hosts


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040340
      - NIST-800-53-CM-6(b)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_x11_forwarding

    - name: Disable X11 Forwarding
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11Forwarding\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11Forwarding\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11Forwarding\s+
          line: X11Forwarding no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040340
      - NIST-800-53-CM-6(b)
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_x11_forwarding


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010830
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_do_not_permit_user_env

    - name: Do Not Allow SSH Environment Options
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
          line: PermitUserEnvironment no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010830
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_do_not_permit_user_env


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010500
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(a)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_strictmodes

    - name: Enable Use of Strict Mode Checking
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*StrictModes\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*StrictModes\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*StrictModes\s+
          line: StrictModes yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010500
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(a)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_strictmodes


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010040
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_warning_banner

    - name: Enable SSH Warning Banner
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*Banner\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*Banner\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*Banner\s+
          line: Banner /etc/issue
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.5.6
      - DISA-STIG-RHEL-08-010040
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_warning_banner


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020350
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_print_last_log

    - name: Enable SSH Print Last Log
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PrintLastLog\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PrintLastLog\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*PrintLastLog\s+
          line: PrintLastLog yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020350
      - NIST-800-53-AC-9
      - NIST-800-53-AC-9(1)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_print_last_log


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040161
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sshd_rekey_limit


    - name: Force frequent session key renegotiation
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*RekeyLimit\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*RekeyLimit\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*RekeyLimit\s+
          line: RekeyLimit {{ var_rekey_limit_size }} {{ var_rekey_limit_time }}
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040161
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sshd_rekey_limit


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010292
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_use_strong_rng

    - name: Setting unquoted shell-style assignment of 'SSH_USE_STRONG_RNG' to '32' in
        '/etc/sysconfig/sshd'
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/sysconfig/sshd
          create: true
          regexp: (?i)^\s*SSH_USE_STRONG_RNG=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/sysconfig/sshd
        lineinfile:
          path: /etc/sysconfig/sshd
          create: true
          regexp: (?i)^\s*SSH_USE_STRONG_RNG=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/sysconfig/sshd
        lineinfile:
          path: /etc/sysconfig/sshd
          create: true
          regexp: (?i)^\s*SSH_USE_STRONG_RNG=
          line: SSH_USE_STRONG_RNG=32
          state: present
          insertbefore: ^# SSH_USE_STRONG_RNG
          validate: /usr/bin/bash -n %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010292
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_use_strong_rng


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040341
      - NIST-800-53-CM-6(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_x11_use_localhost

    - name: Prevent remote hosts from connecting to the proxy display
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11UseLocalhost\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11UseLocalhost\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)(?i)^\s*X11UseLocalhost\s+
          line: X11UseLocalhost yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040341
      - NIST-800-53-CM-6(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_x11_use_localhost


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-010400
      - NIST-800-53-IA-2(11)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_certificate_verification


    - name: Ensure that "certificate_verification" is not set in /etc/sssd/sssd.conf
      ini_file:
        path: /etc/sssd/sssd.conf
        section: sssd
        option: certificate_verification
        state: absent
        mode: 384
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010400
      - NIST-800-53-IA-2(11)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_certificate_verification

    - name: Ensure that "certificate_verification" is not set in  /etc/sssd/conf.d/*.conf
      ini_file:
        path: /etc/sssd/conf.d/*.conf
        section: sssd
        option: certificate_verification
        state: absent
        mode: 384
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010400
      - NIST-800-53-IA-2(11)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_certificate_verification

    - name: Ensure that "certificate_verification" is set
      ini_file:
        path: /etc/sssd/conf.d/certificate_verification.conf
        section: sssd
        option: certificate_verification
        value: ocsp_dgst={{ var_sssd_certificate_verification_digest_function }}
        state: present
        mode: 384
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-010400
      - NIST-800-53-IA-2(11)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_certificate_verification


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Test for domain group
      command: grep '^\s*\[domain\/[^]]*]' /etc/sssd/sssd.conf
      register: test_grep_domain
      failed_when: false
      changed_when: false
      check_mode: false
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Add default domain group (if no domain there)
      ini_file:
        path: /etc/sssd/sssd.conf
        section: '{{ item.section }}'
        option: '{{ item.option }}'
        value: '{{ item.value }}'
        create: true
        mode: 384
      with_items:
      - section: sssd
        option: domains
        value: default
      - section: domain/default
        option: id_provider
        value: files
      when:
      - '"sssd-common" in ansible_facts.packages'
      - test_grep_domain.stdout is defined
      - test_grep_domain.stdout | length < 1
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Enable Smartcards in SSSD
      ini_file:
        dest: /etc/sssd/sssd.conf
        section: pam
        option: pam_cert_auth
        value: 'True'
        create: true
        mode: 384
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Find all the conf files inside /etc/sssd/conf.d/
      find:
        paths: /etc/sssd/conf.d/
        patterns: '*.conf'
      register: sssd_conf_d_files
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Fix pam_cert_auth configuration in /etc/sssd/conf.d/
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: '[^#]*pam_cert_auth.*'
        replace: pam_cert_auth = True
      with_items: '{{ sssd_conf_d_files.files }}'
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Enable Smartcards in SSSD - Check if system relies on authselect
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Enable Smartcards in SSSD - Remediate using authselect
      block:

      - name: Enable Smartcards in SSSD - Check integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        failed_when: false

      - name: Enable Smartcards in SSSD - Informative message based on the authselect
          integrity check result
        ansible.builtin.assert:
          that:
          - result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was not
            selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific demand,
            a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Enable Smartcards in SSSD - Get authselect current features
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Enable Smartcards in SSSD - Ensure "with-smartcard" feature is enabled using
          authselect tool
        ansible.builtin.command:
          cmd: authselect enable-feature with-smartcard
        register: result_authselect_enable_feature_cmd
        when:
        - result_authselect_check_cmd is success
        - result_authselect_features.stdout is not search("with-smartcard")

      - name: Enable Smartcards in SSSD - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_enable_feature_cmd is not skipped
        - result_authselect_enable_feature_cmd is success
      when:
      - '"sssd-common" in ansible_facts.packages'
      - result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards

    - name: Enable Smartcards in SSSD - Remediate by directly editing PAM files
      block:

      - name: Enable Smartcards in SSSD - Define a fact for control already filtered in
          case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Enable Smartcards in SSSD - Check if expected PAM module line is present
          in /etc/pam.d/smartcard-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/smartcard-auth
          regexp: ^\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Enable Smartcards in SSSD - Include or update the PAM module line in /etc/pam.d/smartcard-auth
        block:

        - name: Enable Smartcards in SSSD - Check if required PAM module line is present
            in /etc/pam.d/smartcard-auth with different control
          ansible.builtin.lineinfile:
            path: /etc/pam.d/smartcard-auth
            regexp: ^\s*auth\s+.*\s+pam_sss.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Enable Smartcards in SSSD - Ensure the correct control for the required
            PAM module line in /etc/pam.d/smartcard-auth
          ansible.builtin.replace:
            dest: /etc/pam.d/smartcard-auth
            regexp: ^(\s*auth\s+).*(\bpam_sss.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Enable Smartcards in SSSD - Ensure the required PAM module line is included
            in /etc/pam.d/smartcard-auth
          ansible.builtin.lineinfile:
            dest: /etc/pam.d/smartcard-auth
            line: auth    {{ pam_module_control }}    pam_sss.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Enable Smartcards in SSSD - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Enable Smartcards in SSSD - Define a fact for control already filtered in
          case filters are used
        ansible.builtin.set_fact:
          pam_module_control: sufficient

      - name: Enable Smartcards in SSSD - Check if the required PAM module option is present
          in /etc/pam.d/smartcard-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/smartcard-auth
          regexp: ^\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so\s*.*\sallow_missing_name\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_sssd_enable_smartcards_option_present

      - name: Enable Smartcards in SSSD - Ensure the "allow_missing_name" PAM option for
          "pam_sss.so" is included in /etc/pam.d/smartcard-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/smartcard-auth
          backrefs: true
          regexp: ^(\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so.*)
          line: \1 allow_missing_name
          state: present
        register: result_pam_sssd_enable_smartcards_add
        when:
        - result_pam_module_sssd_enable_smartcards_option_present.found == 0

      - name: Enable Smartcards in SSSD - Define a fact for control already filtered in
          case filters are used
        ansible.builtin.set_fact:
          pam_module_control: '[success=done authinfo_unavail=ignore ignore=ignore default=die]'

      - name: Enable Smartcards in SSSD - Check if expected PAM module line is present
          in /etc/pam.d/system-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: ^\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present

      - name: Enable Smartcards in SSSD - Include or update the PAM module line in /etc/pam.d/system-auth
        block:

        - name: Enable Smartcards in SSSD - Check if required PAM module line is present
            in /etc/pam.d/system-auth with different control
          ansible.builtin.lineinfile:
            path: /etc/pam.d/system-auth
            regexp: ^\s*auth\s+.*\s+pam_sss.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present

        - name: Enable Smartcards in SSSD - Ensure the correct control for the required
            PAM module line in /etc/pam.d/system-auth
          ansible.builtin.replace:
            dest: /etc/pam.d/system-auth
            regexp: ^(\s*auth\s+).*(\bpam_sss.so.*)
            replace: \1{{ pam_module_control }} \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1

        - name: Enable Smartcards in SSSD - Ensure the required PAM module line is included
            in /etc/pam.d/system-auth
          ansible.builtin.lineinfile:
            dest: /etc/pam.d/system-auth
            line: auth    {{ pam_module_control }}    pam_sss.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1

        - name: Enable Smartcards in SSSD - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0

      - name: Enable Smartcards in SSSD - Define a fact for control already filtered in
          case filters are used
        ansible.builtin.set_fact:
          pam_module_control: '[success=done authinfo_unavail=ignore ignore=ignore default=die]'

      - name: Enable Smartcards in SSSD - Check if the required PAM module option is present
          in /etc/pam.d/system-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          regexp: ^\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so\s*.*\stry_cert_auth\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_sssd_enable_smartcards_option_present

      - name: Enable Smartcards in SSSD - Ensure the "try_cert_auth" PAM option for "pam_sss.so"
          is included in /etc/pam.d/system-auth
        ansible.builtin.lineinfile:
          path: /etc/pam.d/system-auth
          backrefs: true
          regexp: ^(\s*auth\s+{{ pam_module_control | regex_escape() }}\s+pam_sss.so.*)
          line: \1 try_cert_auth
          state: present
        register: result_pam_sssd_enable_smartcards_add
        when:
        - result_pam_module_sssd_enable_smartcards_option_present.found == 0
      when:
      - '"sssd-common" in ansible_facts.packages'
      - not result_authselect_present.stat.exists
      tags:
      - DISA-STIG-RHEL-08-020250
      - PCI-DSS-Req-8.3
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_enable_smartcards


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration

    - name: Test for domain group
      command: grep '\s*\[domain\/[^]]*]' /etc/sssd/sssd.conf
      register: test_grep_domain
      failed_when: false
      changed_when: false
      check_mode: false
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration

    - name: Add default domain group (if no domain there)
      ini_file:
        path: /etc/sssd/sssd.conf
        section: '{{ item.section }}'
        option: '{{ item.option }}'
        value: '{{ item.value }}'
        create: true
        mode: 384
      with_items:
      - section: sssd
        option: domains
        value: default
      - section: domain/default
        option: id_provider
        value: files
      when:
      - '"sssd-common" in ansible_facts.packages'
      - test_grep_domain.stdout is defined
      - test_grep_domain.stdout | length < 1
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration

    - name: Configure SSD to Expire Offline Credentials
      ini_file:
        dest: /etc/sssd/sssd.conf
        section: pam
        option: offline_credentials_expiration
        value: 1
        create: true
        mode: 384
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration

    - name: Find all the conf files inside /etc/sssd/conf.d/
      find:
        paths: /etc/sssd/conf.d/
        patterns: '*.conf'
      register: sssd_conf_d_files
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration

    - name: Fix offline_credentials_expiration configuration in /etc/sssd/conf.d/
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: '[^#]*offline_credentials_expiration.*'
        replace: offline_credentials_expiration = 1
      with_items: '{{ sssd_conf_d_files.files }}'
      when: '"sssd-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-020290
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(13)
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - sssd_offline_cred_expiration


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040139
      - NIST-800-53-CM-8(3)
      - NIST-800-53-IA-3
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_usbguard_installed

    - name: Ensure usbguard is installed
      package:
        name: usbguard
        state: present
      when: ( ansible_architecture != "s390x" and "kernel" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-040139
      - NIST-800-53-CM-8(3)
      - NIST-800-53-IA-3
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_usbguard_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040141
      - NIST-800-53-CM-8(3)(a)
      - NIST-800-53-IA-3
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_usbguard_enabled

    - name: Enable the USBGuard Service - Enable service usbguard
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable the USBGuard Service - Enable Service usbguard
        ansible.builtin.systemd:
          name: usbguard
          enabled: true
          state: started
          masked: false
        when:
        - '"usbguard" in ansible_facts.packages'
      when: ( ansible_architecture != "s390x" and "kernel" in ansible_facts.packages )
      tags:
      - DISA-STIG-RHEL-08-040141
      - NIST-800-53-CM-8(3)(a)
      - NIST-800-53-IA-3
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_usbguard_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030603
      - NIST-800-53-AU-2
      - NIST-800-53-CM-8(3)
      - NIST-800-53-IA-3
      - configure_usbguard_auditbackend
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Log USBGuard daemon audit events using Linux Audit
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/usbguard/usbguard-daemon.conf
          create: true
          regexp: (?i)^\s*AuditBackend=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/usbguard/usbguard-daemon.conf
        lineinfile:
          path: /etc/usbguard/usbguard-daemon.conf
          create: true
          regexp: (?i)^\s*AuditBackend=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/usbguard/usbguard-daemon.conf
        lineinfile:
          path: /etc/usbguard/usbguard-daemon.conf
          create: true
          regexp: (?i)^\s*AuditBackend=
          line: AuditBackend=LinuxAudit
          state: present
      when:
      - ( ansible_architecture != "s390x" and "kernel" in ansible_facts.packages )
      - '"usbguard" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030603
      - NIST-800-53-AU-2
      - NIST-800-53-CM-8(3)
      - NIST-800-53-IA-3
      - configure_usbguard_auditbackend
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040140
      - NIST-800-53-CM-8(3)(a)
      - NIST-800-53-IA-3
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - usbguard_generate_policy

    - name: Generate USBGuard Policy
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Check that the /etc/usbguard/rules.conf exists
        stat:
          path: /etc/usbguard/rules.conf
        register: policy_file

      - name: Create USBGuard Policy configuration
        command: usbguard generate-policy
        register: policy
        when: not policy_file.stat.exists or policy_file.stat.size == 0

      - name: Copy the Generated Policy configuration to a persistent file
        copy:
          content: '{{ policy.stdout }}'
          dest: /etc/usbguard/rules.conf
          mode: 384
        when: not policy_file.stat.exists or policy_file.stat.size == 0

      - name: Add comment into /etc/usbguard/rules.conf when system has no USB devices
        lineinfile:
          path: /etc/usbguard/rules.conf
          line: '# No USB devices found'
          state: present
        when: not policy_file.stat.exists or policy_file.stat.size == 0

      - name: Enable service usbguard
        systemd:
          name: usbguard
          enabled: 'yes'
          state: started
          masked: 'no'
      when:
      - ( ansible_architecture != "s390x" and "kernel" in ansible_facts.packages )
      - '"usbguard" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040140
      - NIST-800-53-CM-8(3)(a)
      - NIST-800-53-IA-3
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - usbguard_generate_policy


    - name: Ensure xorg packages are removed
      package:
        name:
        - xorg-x11-server-Xorg
        - xorg-x11-server-common
        - xorg-x11-server-utils
        - xorg-x11-server-Xwayland
        state: absent
      tags:
      - DISA-STIG-RHEL-08-040320
      - NIST-800-53-CM-6(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy
      - xwindows_remove_packages


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-040321
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy
      - xwindows_runlevel_target

    - name: Switch to multi-user runlevel
      file:
        src: /usr/lib/systemd/system/multi-user.target
        dest: /etc/systemd/system/default.target
        state: link
        force: true
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-040321
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy
      - xwindows_runlevel_target


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030180
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AU-12(2)
      - NIST-800-53-AU-14
      - NIST-800-53-AU-2(a)
      - NIST-800-53-AU-7(1)
      - NIST-800-53-AU-7(2)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.1
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_audit_installed

    - name: Ensure audit is installed
      package:
        name: audit
        state: present
      when: '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030180
      - NIST-800-53-AC-7(a)
      - NIST-800-53-AU-12(2)
      - NIST-800-53-AU-14
      - NIST-800-53-AU-2(a)
      - NIST-800-53-AU-7(1)
      - NIST-800-53-AU-7(2)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.1
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_audit_installed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030181
      - NIST-800-171-3.3.1
      - NIST-800-171-3.3.2
      - NIST-800-171-3.3.6
      - NIST-800-53-AC-2(g)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-10
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-14(1)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(23)
      - PCI-DSS-Req-10.1
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_auditd_enabled

    - name: Enable auditd Service - Enable service auditd
      block:

      - name: Gather the package facts
        package_facts:
          manager: auto

      - name: Enable auditd Service - Enable Service auditd
        ansible.builtin.systemd:
          name: auditd
          enabled: true
          state: started
          masked: false
        when:
        - '"audit" in ansible_facts.packages'
      when:
      - '"kernel" in ansible_facts.packages'
      - '"audit" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030181
      - NIST-800-171-3.3.1
      - NIST-800-171-3.3.2
      - NIST-800-171-3.3.6
      - NIST-800-53-AC-2(g)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-10
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-14(1)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-4(23)
      - PCI-DSS-Req-10.1
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_auditd_enabled


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030601
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-17(1)
      - NIST-800-53-AU-10
      - NIST-800-53-AU-14(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IR-5(1)
      - PCI-DSS-Req-10.3
      - PCI-DSSv4-10.7
      - PCI-DSSv4-10.7.2
      - grub2_audit_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy

    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="audit=1"
      when:
      - '"kernel" in ansible_facts.packages'
      - '"grub2-common" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030601
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-17(1)
      - NIST-800-53-AU-10
      - NIST-800-53-AU-14(1)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IR-5(1)
      - PCI-DSS-Req-10.3
      - PCI-DSSv4-10.7
      - PCI-DSSv4-10.7.2
      - grub2_audit_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030602
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-10.7
      - PCI-DSSv4-10.7.2
      - grub2_audit_backlog_limit_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy

    - name: Update grub defaults and the bootloader menu
      command: /sbin/grubby --update-kernel=ALL --args="audit_backlog_limit=8192"
      when:
      - '"kernel" in ansible_facts.packages'
      - '"grub2-common" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030602
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-10.7
      - PCI-DSSv4-10.7.2
      - grub2_audit_backlog_limit_argument
      - low_disruption
      - low_severity
      - medium_complexity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030121
      - NIST-800-171-3.3.1
      - NIST-800-171-3.4.3
      - NIST-800-53-AC-6(9)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.2
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.2
      - audit_rules_immutable
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Collect all files from /etc/audit/rules.d with .rules extension
      find:
        paths: /etc/audit/rules.d/
        patterns: '*.rules'
      register: find_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030121
      - NIST-800-171-3.3.1
      - NIST-800-171-3.4.3
      - NIST-800-53-AC-6(9)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.2
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.2
      - audit_rules_immutable
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Remove the -e option from all Audit config files
      lineinfile:
        path: '{{ item }}'
        regexp: ^\s*(?:-e)\s+.*$
        state: absent
      loop: '{{ find_rules_d.files | map(attribute=''path'') | list + [''/etc/audit/audit.rules'']
        }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030121
      - NIST-800-171-3.3.1
      - NIST-800-171-3.4.3
      - NIST-800-53-AC-6(9)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.2
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.2
      - audit_rules_immutable
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add Audit -e option into /etc/audit/rules.d/immutable.rules and /etc/audit/audit.rules
      lineinfile:
        path: '{{ item }}'
        create: true
        line: -e 2
        mode: o-rwx
      loop:
      - /etc/audit/audit.rules
      - /etc/audit/rules.d/immutable.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030121
      - NIST-800-171-3.3.1
      - NIST-800-171-3.4.3
      - NIST-800-53-AC-6(9)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.2
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.2
      - audit_rules_immutable
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030122
      - audit_rules_immutable_login_uids
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: 'Configure immutable Audit login UIDs: Determine if rules are loaded by auditctl'
      ansible.builtin.find:
        paths: /usr/lib/systemd/system
        patterns: auditd.service
        contains: ^\s*ExecStartPost=-/sbin/auditctl
      register: auditctl_used
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030122
      - audit_rules_immutable_login_uids
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: 'Configure immutable Audit login UIDs: Configure immutable login UIDs in /etc/audit/audit.rules'
      ansible.builtin.lineinfile:
        path: /etc/audit/audit.rules
        line: --loginuid-immutable
        regexp: ^\s*--loginuid-immutable\s*$
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - auditctl_used is defined and auditctl_used.matched >= 1
      tags:
      - DISA-STIG-RHEL-08-030122
      - audit_rules_immutable_login_uids
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: 'Configure immutable Audit login UIDs: In case Augen-rules is used'
      block:

      - name: 'Configure immutable Audit login UIDs: Detect if immutable login UIDs are
          already defined in /etc/audit/rules.d/*.rules'
        ansible.builtin.find:
          paths: /etc/audit/rules.d
          patterns: '*.rules'
          contains: ^\s*--loginuid-immutable\s*$
        register: immutable_found_in_rules_d

      - name: 'Configure immutable Audit login UIDs: set immutable login UIDS in /etc/audit/rules.d/immutable.rules'
        ansible.builtin.lineinfile:
          path: /etc/audit/rules.d/immutable.rules
          line: --loginuid-immutable
          regexp: ^\s*--loginuid-immutable\s*$
          create: true
        when: immutable_found_in_rules_d is defined and immutable_found_in_rules_d.matched
          == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - auditctl_used is defined and auditctl_used.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030122
      - audit_rules_immutable_login_uids
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030302
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_media_export
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit mount tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030302
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_media_export
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for mount for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - mount
          syscall_grouping: []

      - name: Check existence of mount in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - mount
          syscall_grouping: []

      - name: Check existence of mount in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030302
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_media_export
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for mount for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - mount
          syscall_grouping: []

      - name: Check existence of mount in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - mount
          syscall_grouping: []

      - name: Check existence of mount in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030302
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_media_export
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Check if watch rule for /etc/sudoers already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key actions
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)actions$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Use /etc/audit/rules.d/actions.rules as the recipient for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/actions.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Add watch rule for /etc/sudoers in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/sudoers -p wa -k actions
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Check if watch rule for /etc/sudoers already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Add watch rule for /etc/sudoers in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/sudoers -p wa -k actions
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030171
      - audit_rules_sudoers
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Check if watch rule for /etc/sudoers.d/ already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key actions
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)actions$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Use /etc/audit/rules.d/actions.rules as the recipient for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/actions.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Add watch rule for /etc/sudoers.d/ in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/sudoers.d/ -p wa -k actions
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Check if watch rule for /etc/sudoers.d/ already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Add watch rule for /etc/sudoers.d/ in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/sudoers.d/ -p wa -k actions
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030172
      - audit_rules_sudoers_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Service facts
      ansible.builtin.service_facts: null
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set suid_audit_rules fact
      ansible.builtin.set_fact:
        suid_audit_rules:
        - rule: -a always,exit -F arch=b32 -S execve -C gid!=egid -F egid=0 -k setgid
          regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b32[\s]+-S[\s]+execve[\s]+-C[\s]+gid!=egid[\s]+-F[\s]+egid=0[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
        - rule: -a always,exit -F arch=b64 -S execve -C gid!=egid -F egid=0 -k setgid
          regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b64[\s]+-S[\s]+execve[\s]+-C[\s]+gid!=egid[\s]+-F[\s]+egid=0[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
        - rule: -a always,exit -F arch=b32 -S execve -C uid!=euid -F euid=0 -k setuid
          regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b32[\s]+-S[\s]+execve[\s]+-C[\s]+uid!=euid[\s]+-F[\s]+euid=0[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
        - rule: -a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k setuid
          regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b64[\s]+-S[\s]+execve[\s]+-C[\s]+uid!=euid[\s]+-F[\s]+euid=0[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Update /etc/audit/rules.d/privileged.rules to audit privileged functions
      ansible.builtin.lineinfile:
        path: /etc/audit/rules.d/privileged.rules
        line: '{{  item.rule  }}'
        regexp: '{{ item.regex }}'
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ('"auditd.service" in ansible_facts.services' or '"augenrules.service" in ansible_facts.services')
      register: augenrules_audit_rules_privilege_function_update_result
      with_items: '{{ suid_audit_rules }}'
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Update /etc/audit/audit.rules to audit privileged functions
      ansible.builtin.lineinfile:
        path: /etc/audit/audit.rules
        line: '{{  item.rule  }}'
        regexp: '{{ item.regex }}'
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ('"auditd.service" in ansible_facts.services' or '"augenrules.service" in ansible_facts.services')
      register: auditctl_audit_rules_privilege_function_update_result
      with_items: '{{ suid_audit_rules }}'
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Restart Auditd
      ansible.builtin.command: /usr/sbin/service auditd restart
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - (augenrules_audit_rules_privilege_function_update_result.changed or auditctl_audit_rules_privilege_function_update_result.changed)
      - ansible_facts.services["auditd.service"].state == "running"
      tags:
      - DISA-STIG-RHEL-08-030000
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(3)
      - NIST-800-53-AU-7(a)
      - NIST-800-53-AU-7(b)
      - NIST-800-53-AU-8(b)
      - NIST-800-53-CM-5(1)
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.2
      - audit_rules_suid_privilege_function
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/group already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
        for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/group in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/group -p wa -k audit_rules_usergroup_modification
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/group already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/group in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/group -p wa -k audit_rules_usergroup_modification
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030170
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_group
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/gshadow already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
        for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/gshadow in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/gshadow already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/gshadow in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030160
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/security/opasswd already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
        for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/security/opasswd in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/security/opasswd already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/security/opasswd in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030140
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_opasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/passwd already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
        for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/passwd in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/passwd already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/passwd in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030150
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/shadow already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
        for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/shadow in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /etc/shadow already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /etc/shadow in /etc/audit/audit.rules
      lineinfile:
        line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030130
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.5
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.5
      - audit_rules_usergroup_modification_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030110
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_group_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: System Audit Directories Must Be Group Owned By Root - Register Audit Configuration
        Text
      ansible.builtin.slurp:
        src: /etc/audit/auditd.conf
      register: auditd_config_slurp
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030110
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_group_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: System Audit Directories Must Be Group Owned By Root - Set Permissions Custom
        Location
      ansible.builtin.file:
        group: |-
          {{ auditd_config_slurp['content'] | b64decode | regex_findall('
          log_group\s*=\s*(.+)') | default(['root',], boolean=True) | first }}
        path: |-
          {{ auditd_config_slurp['content'] | b64decode | regex_findall('
          log_file\s*=\s*(.+)') | default(['/var/log/audit/audit.log',], boolean=True) | first | dirname }}
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030110
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_group_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030100
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: System Audit Directories Must Be Owned By Root - Register Audit Configuration
        Text
      ansible.builtin.slurp:
        src: /etc/audit/auditd.conf
      register: auditd_config_slurp
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030100
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: System Audit Directories Must Be Owned By Root - Set Permissions Custom Location
      ansible.builtin.file:
        owner: root
        path: |-
          {{ auditd_config_slurp['content'] | b64decode | regex_findall('
          log_file\s*=\s*(.+)') | default(['/var/log/audit/audit.log',], boolean=True) | first | dirname }}
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030100
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.1
      - configure_strategy
      - directory_ownership_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Get audit log files
      command: grep -iw ^log_file /etc/audit/auditd.conf
      failed_when: false
      register: log_file_exists
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Parse log file line
      command: awk -F '=' '/^log_file/ {print $2}' /etc/audit/auditd.conf
      register: log_file_line
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - log_file_exists is not skipped and (log_file_exists.stdout | length > 0)
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set default log_file if not set
      set_fact:
        log_file: /var/log/audit/audit.log
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - (log_file_exists is skipped) or (log_file_exists is undefined) or (log_file_exists.stdout
        | length == 0)
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set log_file from log_file_line if not set already
      set_fact:
        log_file: '{{ log_file_line.stdout | trim }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - (log_file_exists is not skipped) and (log_file_line.stdout is defined) and (log_file_line.stdout
        | length > 0)
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Get log files group
      command: grep -m 1 ^log_group /etc/audit/auditd.conf
      failed_when: false
      register: log_group_line
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Parse log group line
      command: awk -F '=' '/log_group/ {print $2}' /etc/audit/auditd.conf
      register: log_group
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - (log_group_line is not skipped) and (log_group_line.stdout | length > 0)
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Apply mode to log file when group root
      file:
        path: '{{ log_file }}'
        mode: (( log_group is defined ) and ( ( log_group.stdout | trim ) == 'root' ))
          | ternary( '0600', '0640')
      failed_when: false
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - log_group is not skipped
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: List all log file backups
      find:
        path: '{{ log_file | dirname }}'
        patterns: '{{ log_file | basename }}.*'
      register: backup_files
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Apply mode to log file when group not root
      file:
        path: '{{ item }}'
        mode: (( log_group is defined ) and ( ( log_group.stdout | trim ) == 'root' ))  |
          ternary( '0400', '0440')
      loop: '{{ backup_files.files| map(attribute=''path'') | list }}'
      failed_when: false
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - backup_files is not skipped
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030070
      - NIST-800-171-3.3.1
      - NIST-800-53-AC-6(1)
      - NIST-800-53-AU-9(4)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.1
      - file_permissions_var_log_audit
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit chmod tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for chmod for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of chmod in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of chmod in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for chmod for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of chmod in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of chmod in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit chown tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for chown for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of chown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of chown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for chown for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of chown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - chown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of chown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_chown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fchmod tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchmod for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmod in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmod in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchmod for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmod in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmod
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmod in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmod
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmodat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fchmodat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmodat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchmodat for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmodat
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmodat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmodat
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmodat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmodat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchmodat for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmodat
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmodat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchmodat
          syscall_grouping:
          - chmod
          - fchmod
          - fchmodat

      - name: Check existence of fchmodat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030490
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchmodat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fchown tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchown for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchown for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchownat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fchownat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchownat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchownat for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchownat
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchownat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchownat
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchownat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchownat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fchownat for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchownat
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchownat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fchownat
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of fchownat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fchownat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fremovexattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fremovexattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fremovexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fremovexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fremovexattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fremovexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fremovexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit fsetxattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fsetxattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fsetxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fsetxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for fsetxattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fsetxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - fsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of fsetxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_fsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit lchown tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lchown for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of lchown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of lchown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lchown for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of lchown in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lchown
          syscall_grouping:
          - chown
          - fchown
          - fchownat
          - lchown

      - name: Check existence of lchown in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030480
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lchown
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit lremovexattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lremovexattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lremovexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lremovexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lremovexattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lremovexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lremovexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lremovexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lremovexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit lsetxattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lsetxattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lsetxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lsetxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for lsetxattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lsetxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - lsetxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of lsetxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_lsetxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_removexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit removexattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_removexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for removexattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - removexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of removexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - removexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of removexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_removexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for removexattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - removexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of removexattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - removexattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of removexattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_removexattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_setxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit setxattr tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_setxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for setxattr for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - setxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of setxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - setxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of setxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_setxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for setxattr for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - setxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of setxattr in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
        set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - setxattr
          syscall_grouping:
          - fremovexattr
          - lremovexattr
          - removexattr
          - fsetxattr
          - lsetxattr
          - setxattr

      - name: Check existence of setxattr in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=perm_mod
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030200
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.5.5
      - PCI-DSSv4-10.3
      - PCI-DSSv4-10.3.4
      - audit_rules_dac_modification_setxattr
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030570
      - audit_rules_execution_chacl
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/chacl
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chacl -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/chacl -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030570
      - audit_rules_execution_chacl
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030330
      - audit_rules_execution_setfacl
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/setfacl
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/setfacl -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030330
      - audit_rules_execution_setfacl
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030260
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_chcon
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/chcon
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chcon -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chcon -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chcon -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030260
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_chcon
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030313
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_semanage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/semanage
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/semanage -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/semanage -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/semanage -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030313
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_semanage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030314
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_setfiles
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/setfiles
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/setfiles -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/setfiles -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/setfiles -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030314
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_setfiles
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030316
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_setsebool
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/setsebool
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/setsebool -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/setsebool -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/setsebool -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030316
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_execution_setsebool
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rename
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit rename tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rename
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for rename for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rename
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rename in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rename
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rename in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rename
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for rename for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rename
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rename in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rename
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rename in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rename
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_renameat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit renameat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_renameat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for renameat for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - renameat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of renameat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - renameat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of renameat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_renameat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for renameat for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - renameat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of renameat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - renameat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of renameat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_renameat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rmdir
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit rmdir tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rmdir
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for rmdir for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rmdir
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rmdir in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rmdir
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rmdir in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rmdir
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for rmdir for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rmdir
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rmdir in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - rmdir
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of rmdir in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_rmdir
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlink
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit unlink tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlink
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for unlink for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlink
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlink in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlink
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlink in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlink
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for unlink for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlink
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlink in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlink
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlink in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlink
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlinkat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit unlinkat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlinkat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for unlinkat for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlinkat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlinkat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlinkat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlinkat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlinkat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for unlinkat for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlinkat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlinkat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
        set_fact: audit_file="/etc/audit/rules.d/delete.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - unlinkat
          syscall_grouping:
          - unlink
          - unlinkat
          - rename
          - renameat
          - rmdir

      - name: Check existence of unlinkat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
            -F auid!=unset -F key=delete
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030361
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.7
      - audit_rules_file_deletion_events_unlinkat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit creat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for creat EACCES for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for creat EACCES for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for creat EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for creat EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - creat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of creat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_creat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit ftruncate tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for ftruncate EACCES for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for ftruncate EACCES for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for ftruncate EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for ftruncate EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - ftruncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of ftruncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_ftruncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit open tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open EACCES for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open EACCES for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - not ( ansible_architecture == "aarch64" )
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit open_by_handle_at tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open_by_handle_at EACCES for 32bit
        platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open_by_handle_at EACCES for 64bit
        platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open_by_handle_at EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for open_by_handle_at EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - open_by_handle_at
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of open_by_handle_at in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_open_by_handle_at
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit openat tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for openat EACCES for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for openat EACCES for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for openat EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for openat EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - openat
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of openat in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_openat
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Set architecture for audit truncate tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for truncate EACCES for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for truncate EACCES for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for truncate EPERM for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Perform remediation of Audit rules for truncate EPERM for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
        set_fact: audit_file="/etc/audit/rules.d/access.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - truncate
          syscall_grouping:
          - creat
          - ftruncate
          - truncate
          - open
          - openat
          - open_by_handle_at

      - name: Check existence of truncate in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
            -F auid>=1000 -F auid!=unset -F key=access
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030420
      - NIST-800-171-3.1.7
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.1
      - PCI-DSS-Req-10.2.4
      - audit_rules_unsuccessful_file_modification_truncate
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030390
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_delete
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set architecture for audit delete_module tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030390
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_delete
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for delete_module for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - delete_module
          syscall_grouping: []

      - name: Check existence of delete_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - delete_module
          syscall_grouping: []

      - name: Check existence of delete_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030390
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_delete
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for delete_module for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - delete_module
          syscall_grouping: []

      - name: Check existence of delete_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - delete_module
          syscall_grouping: []

      - name: Check existence of delete_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030390
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_delete
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_finit
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set architecture for audit finit_module tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_finit
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for finit_module for x86 platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - finit_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of finit_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - finit_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of finit_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_finit
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for finit_module for x86_64 platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - finit_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of finit_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - finit_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of finit_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_finit
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_init
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Set architecture for audit init_module tasks
      set_fact:
        audit_arch: b64
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
        == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_init
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for init_module for 32bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - init_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of init_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - init_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of init_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_init
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed

    - name: Perform remediation of Audit rules for init_module for 64bit platform
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - init_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of init_module in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules
        set_fact: audit_file="/etc/audit/rules.d/module-change.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls:
          - init_module
          syscall_grouping:
          - init_module
          - finit_module

      - name: Check existence of init_module in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
            |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
            join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - audit_arch == "b64"
      tags:
      - DISA-STIG-RHEL-08-030360
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.7
      - audit_rules_kernel_module_loading_init
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Check if watch rule for {{ var_accounts_passwords_pam_faillock_dir }} already
        exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key logins
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)logins$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/logins.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for {{ var_accounts_passwords_pam_faillock_dir }} already
        exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/audit.rules
      lineinfile:
        line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030590
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_faillock
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /var/log/lastlog already exists in /etc/audit/rules.d/
      find:
        paths: /etc/audit/rules.d
        contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+
        patterns: '*.rules'
      register: find_existing_watch_rules_d
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Search /etc/audit/rules.d for other rules with specified key logins
      find:
        paths: /etc/audit/rules.d
        contains: ^.*(?:-F key=|-k\s+)logins$
        patterns: '*.rules'
      register: find_watch_key
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule
      set_fact:
        all_files:
        - /etc/audit/rules.d/logins.rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Use matched file as the recipient for the rule
      set_fact:
        all_files:
        - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
        is defined and find_existing_watch_rules_d.matched == 0
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /var/log/lastlog in /etc/audit/rules.d/
      lineinfile:
        path: '{{ all_files[0] }}'
        line: -w /var/log/lastlog -p wa -k logins
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Check if watch rule for /var/log/lastlog already exists in /etc/audit/audit.rules
      find:
        paths: /etc/audit/
        contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+
        patterns: audit.rules
      register: find_existing_watch_audit_rules
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy

    - name: Add watch rule for /var/log/lastlog in /etc/audit/audit.rules
      lineinfile:
        line: -w /var/log/lastlog -p wa -k logins
        state: present
        dest: /etc/audit/audit.rules
        create: true
        mode: '0640'
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
        == 0
      tags:
      - DISA-STIG-RHEL-08-030600
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.2.3
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.1
      - PCI-DSSv4-10.2.1.3
      - audit_rules_login_events_lastlog
      - low_complexity
      - low_disruption
      - medium_severity
      - reboot_required
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030250
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_chage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/chage
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chage -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chage -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chage -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chage -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/chage -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chage -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030250
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_chage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030410
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_chsh
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/chsh
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chsh -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chsh -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chsh -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/chsh -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/chsh -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chsh -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030410
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_chsh
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030400
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/crontab
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/crontab -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/crontab -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/crontab -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/crontab -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/crontab -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/crontab -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030400
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030370
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_gpasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/gpasswd
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/gpasswd -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/gpasswd -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/gpasswd -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030370
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_gpasswd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030580
      - NIST-800-53-AU-12(a)
      - NIST-800-53-AU-12.1(ii)
      - NIST-800-53-AU-12.1(iv)AU-12(c)
      - NIST-800-53-AU-3
      - NIST-800-53-AU-3.1
      - NIST-800-53-MA-4(1)(a)
      - audit_rules_privileged_commands_kmod
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/kmod
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/kmod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/kmod -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/kmod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/kmod -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030580
      - NIST-800-53-AU-12(a)
      - NIST-800-53-AU-12.1(ii)
      - NIST-800-53-AU-12.1(iv)AU-12(c)
      - NIST-800-53-AU-3
      - NIST-800-53-AU-3.1
      - NIST-800-53-MA-4(1)(a)
      - audit_rules_privileged_commands_kmod
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030300
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_mount
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/mount
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/mount -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/mount -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/mount -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/mount -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/mount -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/mount -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030300
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_mount
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030350
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_newgrp
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/newgrp
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/newgrp -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/newgrp -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/newgrp -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030350
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_newgrp
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030340
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_pam_timestamp_check
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/pam_timestamp_check
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/pam_timestamp_check
            -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/pam_timestamp_check
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/pam_timestamp_check
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030340
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_pam_timestamp_check
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030290
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/passwd
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/passwd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/passwd -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/passwd -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/passwd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/passwd -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/passwd -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030290
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030311
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_postdrop
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/postdrop
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/postdrop -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/postdrop -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/postdrop -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030311
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_postdrop
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030312
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_postqueue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/postqueue
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/postqueue -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/postqueue -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/postqueue -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030312
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_postqueue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030280
      - audit_rules_privileged_commands_ssh_agent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/ssh-agent
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/ssh-agent -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/ssh-agent -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/ssh-agent -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/ssh-agent -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/ssh-agent -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/ssh-agent -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030280
      - audit_rules_privileged_commands_ssh_agent
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030320
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_ssh_keysign
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/libexec/openssh/ssh-keysign
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/libexec/openssh/ssh-keysign
            -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/libexec/openssh/ssh-keysign
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset
            (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/libexec/openssh/ssh-keysign
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030320
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_ssh_keysign
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030190
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_su
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/su
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/su -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/su -F auid>=1000 -F
            auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/su -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/su -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/su -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/su -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030190
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_su
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030550
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_sudo
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/sudo
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/sudo -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/sudo -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/sudo -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/sudo -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/sudo -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/sudo -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030550
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_sudo
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030301
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_umount
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/bin/umount
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/umount -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/umount -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/umount -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/bin/umount -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/bin/umount -F auid>=1000 -F auid!=unset (?:-k |-F
            key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/umount -F auid>=1000
            -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030301
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_umount
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030317
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(a)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-12.1(ii)
      - NIST-800-53-AU-12.1(iv)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-AU-3
      - NIST-800-53-AU-3.1
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(1)(a)
      - audit_rules_privileged_commands_unix_chkpwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/unix_chkpwd
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/unix_chkpwd -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/unix_chkpwd
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/unix_chkpwd
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030317
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-2(4)
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(a)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-12.1(ii)
      - NIST-800-53-AU-12.1(iv)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-AU-3
      - NIST-800-53-AU-3.1
      - NIST-800-53-CM-6(a)
      - NIST-800-53-MA-4(1)(a)
      - audit_rules_privileged_commands_unix_chkpwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030310
      - audit_rules_privileged_commands_unix_update
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/unix_update
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/unix_update -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/unix_update -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/unix_update
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/unix_update -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/unix_update -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/unix_update
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030310
      - audit_rules_privileged_commands_unix_update
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030315
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_userhelper
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/userhelper
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/userhelper -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/userhelper
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/userhelper
            -F auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030315
      - NIST-800-171-3.1.7
      - NIST-800-53-AC-6(9)
      - NIST-800-53-AU-12(c)
      - NIST-800-53-AU-2(d)
      - NIST-800-53-CM-6(a)
      - audit_rules_privileged_commands_userhelper
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030560
      - audit_rules_privileged_commands_usermod
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Perform remediation of Audit rules for /usr/sbin/usermod
      block:

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/rules.d/
        find:
          paths: /etc/audit/rules.d
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: '*.rules'
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Reset syscalls found per file
        set_fact:
          syscalls_per_file: {}
          found_paths_dict: {}

      - name: Declare syscalls found per file
        set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
          :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
        loop: '{{ find_command.results | selectattr(''matched'') | list }}'

      - name: Declare files where syscalls were found
        set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
          | map(attribute='path') | list }}"

      - name: Count occurrences of syscalls in paths
        set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
          0) }) }}"
        loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
          | list }}'

      - name: Get path with most syscalls
        set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
          | last).key }}"
        when: found_paths | length >= 1

      - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
        set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
        when: found_paths | length == 0

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
            | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/usermod -F auid>=1000
            -F auid!=unset (?:-k |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0

      - name: Declare list of syscalls
        set_fact:
          syscalls: []
          syscall_grouping: []

      - name: Check existence of  in /etc/audit/audit.rules
        find:
          paths: /etc/audit
          contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F
            path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
          patterns: audit.rules
        register: find_command
        loop: '{{ (syscall_grouping + syscalls) | unique }}'

      - name: Set path to /etc/audit/audit.rules
        set_fact: audit_file="/etc/audit/audit.rules"

      - name: Declare found syscalls
        set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
          | list }}"

      - name: Declare missing syscalls
        set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"

      - name: Replace the audit rule in {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:(
            -S |,)\w+)+)( -F path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset (?:-k
            |-F key=)\w+)
          line: \1\2\3{{ missing_syscalls | join("\3") }}\4
          backrefs: true
          state: present
        when: syscalls_found | length > 0 and missing_syscalls | length > 0

      - name: Add the audit rule to {{ audit_file }}
        lineinfile:
          path: '{{ audit_file }}'
          line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F
            auid>=1000 -F auid!=unset -F key=privileged
          create: true
          mode: o-rwx
          state: present
        when: syscalls_found | length == 0
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030560
      - audit_rules_privileged_commands_usermod
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030040
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - auditd_data_disk_error_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure auditd Disk Error Action on Disk Error
      lineinfile:
        dest: /etc/audit/auditd.conf
        line: disk_error_action = {{ var_auditd_disk_error_action.split('|')[0] }}
        regexp: ^\s*disk_error_action\s*=\s*.*$
        state: present
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030040
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - auditd_data_disk_error_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030060
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - auditd_data_disk_full_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure auditd Disk Full Action when Disk Space Is Full
      lineinfile:
        dest: /etc/audit/auditd.conf
        line: disk_full_action = {{ var_auditd_disk_full_action.split('|')[0] }}
        regexp: ^\s*disk_full_action\s*=\s*.*$
        state: present
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030060
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - auditd_data_disk_full_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030020
      - NIST-800-171-3.3.1
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)
      - PCI-DSS-Req-10.7.a
      - auditd_data_retention_action_mail_acct
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure auditd mail_acct Action on Low Disk Space
      lineinfile:
        dest: /etc/audit/auditd.conf
        line: action_mail_acct = {{ var_auditd_action_mail_acct }}
        state: present
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030020
      - NIST-800-171-3.3.1
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)
      - PCI-DSS-Req-10.7.a
      - auditd_data_retention_action_mail_acct
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030731
      - NIST-800-171-3.3.1
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.7
      - PCI-DSSv4-10.5
      - PCI-DSSv4-10.5.1
      - auditd_data_retention_space_left_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure auditd space_left Action on Low Disk Space
      lineinfile:
        dest: /etc/audit/auditd.conf
        line: space_left_action = {{ var_auditd_space_left_action.split('|')[0] }}
        regexp: ^\s*space_left_action\s*=\s*.*$
        state: present
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - CJIS-5.4.1.1
      - DISA-STIG-RHEL-08-030731
      - NIST-800-171-3.3.1
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.7
      - PCI-DSSv4-10.5
      - PCI-DSSv4-10.5.1
      - auditd_data_retention_space_left_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030730
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.7
      - auditd_data_retention_space_left_percentage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Configure auditd space_left on Low Disk Space
      lineinfile:
        dest: /etc/audit/auditd.conf
        line: space_left = {{ var_auditd_space_left_percentage }}%
        regexp: ^\s*space_left\s*=\s*.*$
        state: present
        create: true
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030730
      - NIST-800-53-AU-5(1)
      - NIST-800-53-AU-5(2)
      - NIST-800-53-AU-5(4)
      - NIST-800-53-AU-5(b)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-10.7
      - auditd_data_retention_space_left_percentage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030061
      - NIST-800-53-CM-6
      - auditd_local_events
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Include Local Events in Audit Logs
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*local_events\s*=\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*local_events\s*=\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*local_events\s*=\s*
          line: local_events = yes
          state: present
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030061
      - NIST-800-53-CM-6
      - auditd_local_events
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030063
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6
      - auditd_log_format
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Resolve information before writing to audit logs
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*log_format\s*=\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*log_format\s*=\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*log_format\s*=\s*
          line: log_format = ENRICHED
          state: present
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030063
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6
      - auditd_log_format
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030062
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.2
      - auditd_name_format
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Set type of computer node name logging in audit logs - Define Value to Be
        Used in the Remediation
      ansible.builtin.set_fact: auditd_name_format_split="{{ var_auditd_name_format.split('|')[0]
        }}"
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030062
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.2
      - auditd_name_format
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Set type of computer node name logging in audit logs
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*name_format\s*=\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*name_format\s*=\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*name_format\s*=\s*
          line: name_format = {{ auditd_name_format_split }}
          state: present
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030062
      - NIST-800-53-AU-3
      - NIST-800-53-CM-6
      - PCI-DSSv4-10.2
      - PCI-DSSv4-10.2.2
      - auditd_name_format
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy


    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - DISA-STIG-RHEL-08-030700
      - NIST-800-53-AU-4(1)
      - auditd_overflow_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

    - name: Appropriate Action Must be Setup When the Internal Audit Event Queue is Full
      block:

      - name: Check for duplicate values
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*overflow_action\s*=\s*
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*overflow_action\s*=\s*
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/audit/auditd.conf
        lineinfile:
          path: /etc/audit/auditd.conf
          create: true
          regexp: (?i)(?i)^\s*overflow_action\s*=\s*
          line: overflow_action = syslog
          state: present
      when:
      - '"audit" in ansible_facts.packages'
      - '"kernel" in ansible_facts.packages'
      tags:
      - DISA-STIG-RHEL-08-030700
      - NIST-800-53-AU-4(1)
      - auditd_overflow_action
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy

Youez - 2016 - github.com/yon3zu
LinuXploit