Skip to content

File owners, groupowners, permissions should be able to recurse and file_regex#8404

Merged
ggbecker merged 12 commits intoComplianceAsCode:stabilization-v0.1.61from
yuumasato:file_owners_permissions_recurse_and_symlink
Mar 24, 2022
Merged

File owners, groupowners, permissions should be able to recurse and file_regex#8404
ggbecker merged 12 commits intoComplianceAsCode:stabilization-v0.1.61from
yuumasato:file_owners_permissions_recurse_and_symlink

Conversation

@yuumasato
Copy link
Copy Markdown
Member

Description:

  • Rules file_ownership_library_dirs and file_permissions_library_dirs should recurse and check files down in the tree.
    The rules were only checking the first level of directory.
  • Fix handling of symlinks in the remdiation.
    Now it doesn't try to de-reference the symlink, and remediation changes ownership of the symlink.
  • Fix handling of files with spaces.

Rationale:

Notes

  • This was found because in RHEL7, the first level of `/lib' doesn't have any file, only directories:
[root@localhost ~]# ls /lib
binfmt.d  debug  dracut  firewalld  firmware  games  grub  kbd  kde3  kde4  kdump  kernel  locale  modprobe.d  modules  modules-load.d  NetworkManager  polkit-1  python2.7  rpm  sendmail  sendmail.postfix  sse2  sysctl.d  systemd  tmpfiles.d  tuned  udev  yum-plugins

@yuumasato yuumasato added the bugfix Fixes to reported bugs. label Mar 22, 2022
@yuumasato yuumasato added this to the 0.1.61 milestone Mar 22, 2022
@yuumasato yuumasato requested a review from ggbecker March 22, 2022 19:03
@github-actions
Copy link
Copy Markdown

Start a new ephemeral environment with changes proposed in this pull request:

Open in Gitpod

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 22, 2022

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_audit_configuration' differs:
--- old datastream
+++ new datastream
@@ -1,19 +1,18 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q audit; then
 
-readarray -t files < <(find /etc/audit/)
+readarray -t files < <(find /etc/audit/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^audit(\.rules|d\.conf)$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done
 
 
-
-readarray -t files < <(find /etc/audit/rules.d/)
+readarray -t files < <(find /etc/audit/rules.d/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*\.rules$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done
 

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_audit_configuration' differs:
--- old datastream
+++ new datastream
@@ -29,9 +29,11 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when:
+ - '"audit" in ansible_facts.packages'
+ - item.gid != 0
 with_items:
 - '{{ files_found.files }}'
- when: '"audit" in ansible_facts.packages'
 tags:
 - configure_strategy
 - file_groupownership_audit_configuration
@@ -60,9 +62,11 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when:
+ - '"audit" in ansible_facts.packages'
+ - item.gid != 0
 with_items:
 - '{{ files_found.files }}'
- when: '"audit" in ansible_facts.packages'
 tags:
 - configure_strategy
 - file_groupownership_audit_configuration

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_ownership_audit_configuration' differs:
--- old datastream
+++ new datastream
@@ -1,19 +1,17 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q audit; then
 
-readarray -t files < <(find /etc/audit/)
+readarray -t files < <(find /etc/audit/ -maxdepth 1 ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^audit(\.rules|d\.conf)$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done
 
-
-
-readarray -t files < <(find /etc/audit/rules.d/)
+readarray -t files < <(find /etc/audit/rules.d/ -maxdepth 1 ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*\.rules$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done
 

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_ownership_audit_configuration' differs:
--- old datastream
+++ new datastream
@@ -25,13 +25,15 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$
+- name: Ensure owner on /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when:
+ - '"audit" in ansible_facts.packages'
+ - item.uid != 0
 with_items:
 - '{{ files_found.files }}'
- when: '"audit" in ansible_facts.packages'
 tags:
 - configure_strategy
 - file_ownership_audit_configuration
@@ -56,13 +58,15 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$
+- name: Ensure owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when:
+ - '"audit" in ansible_facts.packages'
+ - item.uid != 0
 with_items:
 - '{{ files_found.files }}'
- when: '"audit" in ansible_facts.packages'
 tags:
 - configure_strategy
 - file_ownership_audit_configuration

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_etc_audit_rulesd' differs:
--- old datastream
+++ new datastream
@@ -1,9 +1,9 @@
 
 
 
-readarray -t files < <(find /etc/audit/rules.d/)
+readarray -t files < <(find /etc/audit/rules.d/ -maxdepth 1)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*rules$'; then
- chmod 0640 $file
+ chmod 0640 "$file"
 fi 
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_etc_audit_rulesd' differs:
--- old datastream
+++ new datastream
@@ -20,6 +20,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0640'
+ when: item.mode != '0640'
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,4 +1,4 @@
 
 
 
-chgrp 0 /var/log/
+find -L /var/log/ -maxdepth 1 -type d -exec chgrp 0 {} \;

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /var/log/
- stat:
+- name: Ensure group owner on /var/log/
+ file:
 path: /var/log/
- register: file_exists
+ state: directory
+ group: '0'
 tags:
 - CCE-83659-3
 - DISA-STIG-RHEL-08-010260
@@ -11,18 +12,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /var/log/
- file:
- path: /var/log/
- group: '0'
- when: file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-83659-3
- - DISA-STIG-RHEL-08-010260
- - configure_strategy
- - file_groupowner_var_log
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,4 +1,4 @@
 
 
 
-chown 0 /var/log/
+find -L /var/log/ -maxdepth 1 -type d -exec chown 0 {} \;

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /var/log/
- stat:
+- name: Ensure owner on directory /var/log/
+ file:
 path: /var/log/
- register: file_exists
+ state: directory
+ owner: '0'
 tags:
 - CCE-83661-9
 - DISA-STIG-RHEL-08-010250
@@ -11,18 +12,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /var/log/
- file:
- path: /var/log/
- owner: '0'
- when: file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-83661-9
- - DISA-STIG-RHEL-08-010250
- - configure_strategy
- - file_owner_var_log
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,4 +1,4 @@
 
 
 
-chmod 0755 /var/log/
+find -L /var/log/ -maxdepth 1 -type d -exec chmod 0755 {} \;

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_var_log' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /var/log/
- stat:
+- name: Set permissions for /var/log/
+ file:
 path: /var/log/
- register: file_exists
+ state: directory
+ mode: '0755'
 tags:
 - CCE-83663-5
 - DISA-STIG-RHEL-08-010240
@@ -11,18 +12,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0755 on /var/log/
- file:
- path: /var/log/
- mode: '0755'
- when: file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-83663-5
- - DISA-STIG-RHEL-08-010240
- - configure_strategy
- - file_permissions_var_log
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_dir_group_ownership_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,16 +1,10 @@
 
 
 
-find -L /lib/ -type d -exec chgrp 0 {} \;
+find -L /lib/ -type d -exec chgrp 0 {} \;
 
+find -L /lib64/ -type d -exec chgrp 0 {} \;
 
+find -L /usr/lib/ -type d -exec chgrp 0 {} \;
 
-find -L /lib64/ -type d -exec chgrp 0 {} \;
-
-
-
-find -L /usr/lib/ -type d -exec chgrp 0 {} \;
-
-
-
-find -L /usr/lib64/ -type d -exec chgrp 0 {} \;
+find -L /usr/lib64/ -type d -exec chgrp 0 {} \;

bash remediation for rule 'xccdf_org.ssgproject.content_rule_dir_ownership_binary_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,24 +1,14 @@
 
 
 
-find -L /bin/ -type d -exec chown 0 {} \;
+find -L /bin/ -type d -exec chown 0 {} \;
 
+find -L /sbin/ -type d -exec chown 0 {} \;
 
+find -L /usr/bin/ -type d -exec chown 0 {} \;
 
-find -L /sbin/ -type d -exec chown 0 {} \;
+find -L /usr/sbin/ -type d -exec chown 0 {} \;
 
+find -L /usr/local/bin/ -type d -exec chown 0 {} \;
 
-
-find -L /usr/bin/ -type d -exec chown 0 {} \;
-
-
-
-find -L /usr/sbin/ -type d -exec chown 0 {} \;
-
-
-
-find -L /usr/local/bin/ -type d -exec chown 0 {} \;
-
-
-
-find -L /usr/local/sbin/ -type d -exec chown 0 {} \;
+find -L /usr/local/sbin/ -type d -exec chown 0 {} \;

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_dir_ownership_binary_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,4 +1,4 @@
-- name: Ensure owner on /bin/ recursively
+- name: Ensure owner on directory /bin/ recursively
 file:
 path: /bin/
 state: directory
@@ -12,7 +12,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /sbin/ recursively
+- name: Ensure owner on directory /sbin/ recursively
 file:
 path: /sbin/
 state: directory
@@ -26,7 +26,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/bin/ recursively
+- name: Ensure owner on directory /usr/bin/ recursively
 file:
 path: /usr/bin/
 state: directory
@@ -40,7 +40,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/sbin/ recursively
+- name: Ensure owner on directory /usr/sbin/ recursively
 file:
 path: /usr/sbin/
 state: directory
@@ -54,7 +54,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/local/bin/ recursively
+- name: Ensure owner on directory /usr/local/bin/ recursively
 file:
 path: /usr/local/bin/
 state: directory
@@ -68,7 +68,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/local/sbin/ recursively
+- name: Ensure owner on directory /usr/local/sbin/ recursively
 file:
 path: /usr/local/sbin/
 state: directory

bash remediation for rule 'xccdf_org.ssgproject.content_rule_dir_ownership_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,16 +1,10 @@
 
 
 
-find -L /lib/ -type d -exec chown 0 {} \;
+find -L /lib/ -type d -exec chown 0 {} \;
 
+find -L /lib64/ -type d -exec chown 0 {} \;
 
+find -L /usr/lib/ -type d -exec chown 0 {} \;
 
-find -L /lib64/ -type d -exec chown 0 {} \;
-
-
-
-find -L /usr/lib/ -type d -exec chown 0 {} \;
-
-
-
-find -L /usr/lib64/ -type d -exec chown 0 {} \;
+find -L /usr/lib64/ -type d -exec chown 0 {} \;

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_dir_ownership_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,4 +1,4 @@
-- name: Ensure owner on /lib/ recursively
+- name: Ensure owner on directory /lib/ recursively
 file:
 path: /lib/
 state: directory
@@ -16,7 +16,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /lib64/ recursively
+- name: Ensure owner on directory /lib64/ recursively
 file:
 path: /lib64/
 state: directory
@@ -34,7 +34,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/lib/ recursively
+- name: Ensure owner on directory /usr/lib/ recursively
 file:
 path: /usr/lib/
 state: directory
@@ -52,7 +52,7 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure owner on /usr/lib64/ recursively
+- name: Ensure owner on directory /usr/lib64/ recursively
 file:
 path: /usr/lib64/
 state: directory

bash remediation for rule 'xccdf_org.ssgproject.content_rule_dir_permissions_binary_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,24 +1,14 @@
 
 
 
-find -L /bin/ -type d -exec chmod 0755 {} \;
+find -L /bin/ -type d -exec chmod 0755 {} \;
 
+find -L /sbin/ -type d -exec chmod 0755 {} \;
 
+find -L /usr/bin/ -type d -exec chmod 0755 {} \;
 
-find -L /sbin/ -type d -exec chmod 0755 {} \;
+find -L /usr/sbin/ -type d -exec chmod 0755 {} \;
 
+find -L /usr/local/bin/ -type d -exec chmod 0755 {} \;
 
-
-find -L /usr/bin/ -type d -exec chmod 0755 {} \;
-
-
-
-find -L /usr/sbin/ -type d -exec chmod 0755 {} \;
-
-
-
-find -L /usr/local/bin/ -type d -exec chmod 0755 {} \;
-
-
-
-find -L /usr/local/sbin/ -type d -exec chmod 0755 {} \;
+find -L /usr/local/sbin/ -type d -exec chmod 0755 {} \;

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_ownership_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,36 +1,30 @@
 
 
 
-readarray -t files < <(find /lib/)
+readarray -t files < <(find /lib/ ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done
 
-
-
-readarray -t files < <(find /lib64/)
+readarray -t files < <(find /lib64/ ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done
 
-
-
-readarray -t files < <(find /usr/lib/)
+readarray -t files < <(find /usr/lib/ ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done
 
-
-
-readarray -t files < <(find /usr/lib64/)
+readarray -t files < <(find /usr/lib64/ ! -uid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chown 0 $file
+ chown -h 0 "$file"
 fi
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_ownership_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,8 +1,9 @@
-- name: Find /lib/ file(s) matching ^.*$
+- name: Find /lib/ file(s) matching ^.*$ recursively
 find:
 paths: /lib/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -19,10 +20,11 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /lib/ file(s) matching ^.*$
+- name: Ensure owner on /lib/ file(s) matching ^.*$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when: item.uid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -39,11 +41,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /lib64/ file(s) matching ^.*$
+- name: Find /lib64/ file(s) matching ^.*$ recursively
 find:
 paths: /lib64/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -60,10 +63,11 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /lib64/ file(s) matching ^.*$
+- name: Ensure owner on /lib64/ file(s) matching ^.*$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when: item.uid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -80,11 +84,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /usr/lib/ file(s) matching ^.*$
+- name: Find /usr/lib/ file(s) matching ^.*$ recursively
 find:
 paths: /usr/lib/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -101,10 +106,11 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /usr/lib/ file(s) matching ^.*$
+- name: Ensure owner on /usr/lib/ file(s) matching ^.*$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when: item.uid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -121,11 +127,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /usr/lib64/ file(s) matching ^.*$
+- name: Find /usr/lib64/ file(s) matching ^.*$ recursively
 find:
 paths: /usr/lib64/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -142,10 +149,11 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Ensure group owner on /usr/lib64/ file(s) matching ^.*$
+- name: Ensure owner on /usr/lib64/ file(s) matching ^.*$
 file:
 path: '{{ item.path }}'
 owner: '0'
+ when: item.uid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,36 +1,30 @@
 
 
 
-readarray -t files < <(find /lib/)
+readarray -t files < <(find /lib/ )
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0755 $file
+ chmod 0755 "$file"
 fi 
 done
 
-
-
-readarray -t files < <(find /lib64/)
+readarray -t files < <(find /lib64/ )
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0755 $file
+ chmod 0755 "$file"
 fi 
 done
 
-
-
-readarray -t files < <(find /usr/lib/)
+readarray -t files < <(find /usr/lib/ )
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0755 $file
+ chmod 0755 "$file"
 fi 
 done
 
-
-
-readarray -t files < <(find /usr/lib64/)
+readarray -t files < <(find /usr/lib64/ )
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0755 $file
+ chmod 0755 "$file"
 fi 
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_library_dirs' differs:
--- old datastream
+++ new datastream
@@ -1,8 +1,9 @@
-- name: Find /lib/ file(s)
+- name: Find /lib/ file(s) recursively
 find:
 paths: /lib/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -23,6 +24,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0755'
+ when: item.mode != '0755'
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -39,11 +41,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /lib64/ file(s)
+- name: Find /lib64/ file(s) recursively
 find:
 paths: /lib64/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -64,6 +67,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0755'
+ when: item.mode != '0755'
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -80,11 +84,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /usr/lib/ file(s)
+- name: Find /usr/lib/ file(s) recursively
 find:
 paths: /usr/lib/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -105,6 +110,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0755'
+ when: item.mode != '0755'
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -121,11 +127,12 @@
 - medium_severity
 - no_reboot_needed
 
-- name: Find /usr/lib64/ file(s)
+- name: Find /usr/lib64/ file(s) recursively
 find:
 paths: /usr/lib64/
 patterns: ^.*$
 use_regex: true
+ recurse: true
 hidden: true
 register: files_found
 tags:
@@ -146,6 +153,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0755'
+ when: item.mode != '0755'
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_root_permissions_syslibrary_files' differs:
--- old datastream
+++ new datastream
@@ -1,36 +1,33 @@
 
 
 
-readarray -t files < <(find /lib/)
+readarray -t files < <(find /lib/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done
 
 
-
-readarray -t files < <(find /lib64/)
+readarray -t files < <(find /lib64/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done
 
 
-
-readarray -t files < <(find /usr/lib/)
+readarray -t files < <(find /usr/lib/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done
 
 
-
-readarray -t files < <(find /usr/lib64/)
+readarray -t files < <(find /usr/lib64/ -maxdepth 1 ! -gid 0)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chgrp 0 $file
+ chgrp -h 0 "$file"
 fi
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_root_permissions_syslibrary_files' differs:
--- old datastream
+++ new datastream
@@ -21,6 +21,7 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when: item.gid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -58,6 +59,7 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when: item.gid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -95,6 +97,7 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when: item.gid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:
@@ -132,6 +135,7 @@
 file:
 path: '{{ item.path }}'
 group: '0'
+ when: item.gid != 0
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chgrp 0 /etc/cron.d/
+find -L /etc/cron.d/ -maxdepth 1 -type d -exec chgrp 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.d/
- stat:
+- name: Ensure group owner on /etc/cron.d/
+ file:
 path: /etc/cron.d/
- register: file_exists
+ state: directory
+ group: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82268-4
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /etc/cron.d/
- file:
- path: /etc/cron.d/
- group: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82268-4
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_groupowner_cron_d
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chgrp 0 /etc/cron.daily/
+find -L /etc/cron.daily/ -maxdepth 1 -type d -exec chgrp 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.daily/
- stat:
+- name: Ensure group owner on /etc/cron.daily/
+ file:
 path: /etc/cron.daily/
- register: file_exists
+ state: directory
+ group: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82234-6
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /etc/cron.daily/
- file:
- path: /etc/cron.daily/
- group: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82234-6
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_groupowner_cron_daily
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chgrp 0 /etc/cron.hourly/
+find -L /etc/cron.hourly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.hourly/
- stat:
+- name: Ensure group owner on /etc/cron.hourly/
+ file:
 path: /etc/cron.hourly/
- register: file_exists
+ state: directory
+ group: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82227-0
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /etc/cron.hourly/
- file:
- path: /etc/cron.hourly/
- group: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82227-0
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_groupowner_cron_hourly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chgrp 0 /etc/cron.monthly/
+find -L /etc/cron.monthly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.monthly/
- stat:
+- name: Ensure group owner on /etc/cron.monthly/
+ file:
 path: /etc/cron.monthly/
- register: file_exists
+ state: directory
+ group: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82256-9
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /etc/cron.monthly/
- file:
- path: /etc/cron.monthly/
- group: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82256-9
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_groupowner_cron_monthly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chgrp 0 /etc/cron.weekly/
+find -L /etc/cron.weekly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupowner_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.weekly/
- stat:
+- name: Ensure group owner on /etc/cron.weekly/
+ file:
 path: /etc/cron.weekly/
- register: file_exists
+ state: directory
+ group: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82244-5
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure group owner 0 on /etc/cron.weekly/
- file:
- path: /etc/cron.weekly/
- group: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82244-5
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_groupowner_cron_weekly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chown 0 /etc/cron.d/
+find -L /etc/cron.d/ -maxdepth 1 -type d -exec chown 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.d/
- stat:
+- name: Ensure owner on directory /etc/cron.d/
+ file:
 path: /etc/cron.d/
- register: file_exists
+ state: directory
+ owner: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82272-6
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /etc/cron.d/
- file:
- path: /etc/cron.d/
- owner: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82272-6
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_owner_cron_d
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chown 0 /etc/cron.daily/
+find -L /etc/cron.daily/ -maxdepth 1 -type d -exec chown 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.daily/
- stat:
+- name: Ensure owner on directory /etc/cron.daily/
+ file:
 path: /etc/cron.daily/
- register: file_exists
+ state: directory
+ owner: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82237-9
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /etc/cron.daily/
- file:
- path: /etc/cron.daily/
- owner: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82237-9
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_owner_cron_daily
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chown 0 /etc/cron.hourly/
+find -L /etc/cron.hourly/ -maxdepth 1 -type d -exec chown 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.hourly/
- stat:
+- name: Ensure owner on directory /etc/cron.hourly/
+ file:
 path: /etc/cron.hourly/
- register: file_exists
+ state: directory
+ owner: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82209-8
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /etc/cron.hourly/
- file:
- path: /etc/cron.hourly/
- owner: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82209-8
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_owner_cron_hourly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chown 0 /etc/cron.monthly/
+find -L /etc/cron.monthly/ -maxdepth 1 -type d -exec chown 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.monthly/
- stat:
+- name: Ensure owner on directory /etc/cron.monthly/
+ file:
 path: /etc/cron.monthly/
- register: file_exists
+ state: directory
+ owner: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82260-1
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /etc/cron.monthly/
- file:
- path: /etc/cron.monthly/
- owner: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82260-1
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_owner_cron_monthly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chown 0 /etc/cron.weekly/
+find -L /etc/cron.weekly/ -maxdepth 1 -type d -exec chown 0 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_owner_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.weekly/
- stat:
+- name: Ensure owner on directory /etc/cron.weekly/
+ file:
 path: /etc/cron.weekly/
- register: file_exists
+ state: directory
+ owner: '0'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82247-8
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure owner 0 on /etc/cron.weekly/
- file:
- path: /etc/cron.weekly/
- owner: '0'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82247-8
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_owner_cron_weekly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chmod 0700 /etc/cron.d/
+find -L /etc/cron.d/ -maxdepth 1 -type d -exec chmod 0700 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_d' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.d/
- stat:
+- name: Set permissions for /etc/cron.d/
+ file:
 path: /etc/cron.d/
- register: file_exists
+ state: directory
+ mode: '0700'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82277-5
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0700 on /etc/cron.d/
- file:
- path: /etc/cron.d/
- mode: '0700'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82277-5
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_permissions_cron_d
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chmod 0700 /etc/cron.daily/
+find -L /etc/cron.daily/ -maxdepth 1 -type d -exec chmod 0700 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_daily' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.daily/
- stat:
+- name: Set permissions for /etc/cron.daily/
+ file:
 path: /etc/cron.daily/
- register: file_exists
+ state: directory
+ mode: '0700'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82240-3
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0700 on /etc/cron.daily/
- file:
- path: /etc/cron.daily/
- mode: '0700'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82240-3
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_permissions_cron_daily
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chmod 0700 /etc/cron.hourly/
+find -L /etc/cron.hourly/ -maxdepth 1 -type d -exec chmod 0700 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_hourly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.hourly/
- stat:
+- name: Set permissions for /etc/cron.hourly/
+ file:
 path: /etc/cron.hourly/
- register: file_exists
+ state: directory
+ mode: '0700'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82230-4
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0700 on /etc/cron.hourly/
- file:
- path: /etc/cron.hourly/
- mode: '0700'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82230-4
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_permissions_cron_hourly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chmod 0700 /etc/cron.monthly/
+find -L /etc/cron.monthly/ -maxdepth 1 -type d -exec chmod 0700 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_monthly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.monthly/
- stat:
+- name: Set permissions for /etc/cron.monthly/
+ file:
 path: /etc/cron.monthly/
- register: file_exists
+ state: directory
+ mode: '0700'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82263-5
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0700 on /etc/cron.monthly/
- file:
- path: /etc/cron.monthly/
- mode: '0700'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82263-5
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_permissions_cron_monthly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,7 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-chmod 0700 /etc/cron.weekly/
+find -L /etc/cron.weekly/ -maxdepth 1 -type d -exec chmod 0700 {} \;
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_cron_weekly' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,8 @@
-- name: Test for existence /etc/cron.weekly/
- stat:
+- name: Set permissions for /etc/cron.weekly/
+ file:
 path: /etc/cron.weekly/
- register: file_exists
+ state: directory
+ mode: '0700'
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82253-6
@@ -13,21 +14,3 @@
 - low_disruption
 - medium_severity
 - no_reboot_needed
-
-- name: Ensure permission 0700 on /etc/cron.weekly/
- file:
- path: /etc/cron.weekly/
- mode: '0700'
- when:
- - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- - file_exists.stat is defined and file_exists.stat.exists
- tags:
- - CCE-82253-6
- - NIST-800-53-AC-6(1)
- - NIST-800-53-CM-6(a)
- - configure_strategy
- - file_permissions_cron_weekly
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_httpd_server_conf_d_files' differs:
--- old datastream
+++ new datastream
@@ -1,9 +1,9 @@
 
 
 
-readarray -t files < <(find /etc/httpd/conf.d/)
+readarray -t files < <(find /etc/httpd/conf.d/ -maxdepth 1)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0640 $file
+ chmod 0640 "$file"
 fi 
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_httpd_server_conf_d_files' differs:
--- old datastream
+++ new datastream
@@ -21,6 +21,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0640'
+ when: item.mode != '0640'
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_httpd_server_conf_files' differs:
--- old datastream
+++ new datastream
@@ -1,9 +1,9 @@
 
 
 
-readarray -t files < <(find /etc/httpd/conf/)
+readarray -t files < <(find /etc/httpd/conf/ -maxdepth 1)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*$'; then
- chmod 0640 $file
+ chmod 0640 "$file"
 fi 
 done

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_httpd_server_conf_files' differs:
--- old datastream
+++ new datastream
@@ -21,6 +21,7 @@
 file:
 path: '{{ item.path }}'
 mode: '0640'
+ when: item.mode != '0640'
 with_items:
 - '{{ files_found.files }}'
 tags:

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_sshd_private_key' differs:
--- old datastream
+++ new datastream
@@ -1,10 +1,10 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-readarray -t files < <(find /etc/ssh/)
+readarray -t files < <(find /etc/ssh/ -maxdepth 1)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*_key$'; then
- chmod 0600 $file
+ chmod 0600 "$file"
 fi 
 done
 

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_sshd_private_key' differs:
--- old datastream
+++ new datastream
@@ -25,9 +25,11 @@
 file:
 path: '{{ item.path }}'
 mode: '0600'
+ when:
+ - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
+ - item.mode != '0600'
 with_items:
 - '{{ files_found.files }}'
- when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82424-3
 - DISA-STIG-RHEL-08-010490

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_sshd_pub_key' differs:
--- old datastream
+++ new datastream
@@ -1,10 +1,10 @@
 # Remediation is applicable only in certain platforms
 if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
 
-readarray -t files < <(find /etc/ssh/)
+readarray -t files < <(find /etc/ssh/ -maxdepth 1)
 for file in "${files[@]}"; do
 if basename $file | grep -qE '^.*.pub$'; then
- chmod 0644 $file
+ chmod 0644 "$file"
 fi 
 done
 

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_sshd_pub_key' differs:
--- old datastream
+++ new datastream
@@ -25,9 +25,11 @@
 file:
 path: '{{ item.path }}'
 mode: '0644'
+ when:
+ - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
+ - item.mode != '0644'
 with_items:
 - '{{ files_found.files }}'
- when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CCE-82428-4
 - DISA-STIG-RHEL-08-010480

@yuumasato yuumasato force-pushed the file_owners_permissions_recurse_and_symlink branch from f9d262f to 74f1236 Compare March 22, 2022 21:02
@vojtapolasek vojtapolasek self-assigned this Mar 23, 2022
Add test to check if OVAL is verifying ownership of files in directories
deeper into the library dirs tree.
In file_owner, file_groupowner and file_permissions template,
'recursive' and 'file_regex' should not be mutually exclusive.

The template as it was could not recurse in the specified 'filepath' and
match the file againt 'file_regex'.
@yuumasato yuumasato force-pushed the file_owners_permissions_recurse_and_symlink branch from 74f1236 to d5a23b4 Compare March 23, 2022 14:53
Comment thread shared/templates/file_permissions/oval.template Outdated
@yuumasato
Copy link
Copy Markdown
Member Author

CC @dodys

- /lib64/
- /usr/lib/
- /usr/lib64/
recursive: 'true'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really needed or is it an issue related to PR #8194 ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

@yuumasato yuumasato Mar 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are looking at the same problem, but proposed different solutions, that, at the end, depend on rule interpretation.

When I read the rule description, I interpret that it should go down into all libraries and check files in libraries' directories too, not just the first level.

Copy link
Copy Markdown
Contributor

@dodys dodys Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I'm confused (I'll be honest, it's so many rules touching permissions that I have to re-read it all the time), but this rule specifically has the file_regex, shouldn't it be working recursively as you added to the documentation?
I ran a test and can see that the bash (not sure on ansible though) is correctly going through all the files. Isn't it just a matter of fixing the oval?

Copy link
Copy Markdown
Member Author

@yuumasato yuumasato Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this rule specifically has the file_regex, shouldn't it be working recursively as you added to the documentation?

Hmm, my addition in the documentation is about what will be checked, directories vs files. It doesn't address recursion.
a. If filepath is a directory and file_regex is not specified, the rule will check and remediate the first level of directories in the filepath.
b. If filepath is a directory and file_regex is specified, the rule will check and remediate files in the filepath.

If along with case a., recursion is set, the rule will check directories while recursing down.
If along with case b., recursion is set, the rule will check files while recursing down.

I ran a test and can see that the bash (not sure on ansible though) is correctly going through all the files.

Yes, the remediation is going down the directory tree, but should it happen when I didn't set recursive?

Isn't it just a matter of fixing the oval?

Yes, the OVAL was the part that initially needed fixing, but then I addressed inconsistencies between what the OVAL does and the remediation does.
I think if the check is recursive, the remediation should be too. But if the OVAL isn't recursive, the remediation shouldn't be.

Copy link
Copy Markdown
Contributor

@dodys dodys Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, in RHEL /lib is a symlink to /usr/lib. @dodys Do you mean when the symlink itself is missing, or when the path pointed to by the symlink is missing? It seems to me that missing_file_pass will affect the first case, when the symlink itself is absent. I think symlink_test will be needed to check if the file pointed to is missing.

No, my point is that with the mentioned commit id, it started to filter out symlinks in the oval. Therefore, if /lib is a symlink it won't be checked. If it won't be checked than the number of files evaluated is 0 for that test, thus evaluating to false and the whole rule will fail as the oval is set to all_exist. By passing missing_file_pass in the rule, then it changes from all_exist to any_exist and allow the rule to pass. It is a quick fix.

Out of a review item with Matthew I filed #8412. The expected behaviour of the rule around around symlinks is not clear to me.

I don't really remember if most/any of the permissions/ownership/group ownership rules really mention about symlinks. If oval is set to exclude symlinks (as it is right now), then I don't see the point (and feel free to correct me here) of passing -h in the remediation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Therefore, if /lib is a symlink it won't be checked. If it won't be checked than the number of files evaluated is 0 for that test, thus evaluating to false and the whole rule will fail as the oval is set to all_exist.

From what I could test with changes in this PR (using --oval-results), in RHEL, even when /lib is a symlink the scanner was able to collect objects.
So actually, could it be that the scanner follows symlinks, but doesn't report them as collected objects, 🤔 ?

Attached is the oval-results file:
rhel7-oval-results.zip

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really remember if most/any of the permissions/ownership/group ownership rules really mention about symlinks.

I don't think symlinks are mentioned anywhere.

If oval is set to exclude symlinks (as it is right now), then I don't see the point (and feel free to correct me here) of passing -h in the remediation.

I see, it is strange to change the owner of the symlink when the check ignores them.
The intent of the change was to avoid dereferencing erors when the symlink is broken. (I made that commit when I was still not aware of the symlink mess)
With -h it means that chown will not affect the file pointed to, but as the the find command doesn't follow symlinks by default (and -L is not set), the file pointed to by the symlink wouldn't be changed anyway...but now we avoid dereferencing errors!

And I see inconsistency here too.

To better align with the check the remediation should filter out symlinks before doing chown... But then we are not sure if we actually want to filter out the symlinks...

I'm aware that bdc5989 doesn't fix the symlinking situation, it just avoids errors in chwon command with the current behaviour.
This PR was to improve inconsistency with recurse and file_regex and I stumbled upon symlink and chwon inconsistency, 😂

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just checked here my test from yesterday on master,
so /lib and /lib64 are both symlinks to /usr/lib and /usr/lib64 respectively.
One of the rules that I see failing file_ownership_library_dirs will fail for /lib64 as the only file inside it is a .so that is a symlink to a .so under /usr/lib64.
It doesn't fail for /lib as it "finds" some files there, which are actually files under /usr/lib.

It is tricky and I need to dig deeper on those rules, just not having the time lately.
I have to test with your changes, it might be that all this recursive and changes might fix some of the weirdness I saw in the failing tests.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is tricky. I had to take some time to wrap my head around what the rules do.

Let us know how the tests on your side go.

@yuumasato yuumasato force-pushed the file_owners_permissions_recurse_and_symlink branch 3 times, most recently from 9e97a77 to 03317f6 Compare March 23, 2022 17:45
Mab879
Mab879 previously requested changes Mar 23, 2022
Comment thread shared/templates/file_groupowner/ansible.template
Comment thread shared/templates/file_owner/ansible.template
The remediation performs a 'find' followed by a 'chwon'
While 'find' doesn't follow symlinks by default, 'chown' does follow,
so 'chown' will try to change owner of a non existent file while 'find'
pointed out that the symlink has wrong owner.

While this doesn't affect the result of the evaluation, this avoids messages
like these in the HTML report:

chown: cannot dereference '/lib/faulty_symlink': No such file or directory
chown: cannot dereference '/usr/lib/faulty_symlink': No such file or directory
This changes the remediation to only apply the chwon command on files
that are not compliant, this optimizes the remediation a bit.
Make Ansible remediation the follwing templates handle 'file_regex' and
'recurse' independently:
- file_owner
- file_groupowner
- file_permissions

The template deals with files when 'file_regex' is set, otherwise it
deals with directories.
When 'recurse' is true, the check and remediation will travel down the
directory tree, otherwise only the first level is checked.
This not only speeds up the Ansible remediation but also ensures that we
only touch files that should be modified.
Make Bash remediation of the following templates handle 'file_regex' and
'recurse' independently:
-file_owner
-file_groupowner
-file_permissions
The following templates act only on files or on directories under the
specified filepath.
Add beginning of string anchor to optimize regular expression matching.
@Mab879 Mab879 self-assigned this Mar 23, 2022
After templates file_owner, file_groupowner and file_permissions was
updated to handle simultaneous use of `recurse` and `file_regex` in
commit 4c71f7e and
4c71f7e, the rule changed to
file_permissions_library_dirs only handle only file permissions, not
directory permissions (which is kind of expected).

The rule for directorires is dir_permissions_library_dirs
Surround mode with quotes so it is interpreted as string
@ggbecker ggbecker self-assigned this Mar 24, 2022
@yuumasato yuumasato changed the title File owners permissions recurse and symlink File owners, groupowners, permissions should be able to recurse and file_regex Mar 24, 2022
Copy link
Copy Markdown
Member

@ggbecker ggbecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ggbecker ggbecker dismissed Mab879’s stale review March 24, 2022 11:06

request has been addressed already

@ggbecker ggbecker merged commit f575bda into ComplianceAsCode:stabilization-v0.1.61 Mar 24, 2022
@yuumasato yuumasato deleted the file_owners_permissions_recurse_and_symlink branch March 24, 2022 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fixes to reported bugs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants