Skip to content

Stabilization: Support remote users in file_groupownership_home_directories rule - #15038

Merged
Mab879 merged 1 commit into
ComplianceAsCode:stabilizationfrom
ggbecker:backport_15008
Aug 25, 2026
Merged

Stabilization: Support remote users in file_groupownership_home_directories rule#15038
Mab879 merged 1 commit into
ComplianceAsCode:stabilizationfrom
ggbecker:backport_15008

Conversation

@ggbecker

Copy link
Copy Markdown
Member

Backport of #15008

Update file_groupownership_home_directories rule to support remote users
(LDAP, SSSD, NIS) and align with STIG RHEL-09-411070 requirements.

Changes:
- OVAL: Switch from textfilecontent54_object to unix:password_object
  using create_interactive_users_list_object macro to support getpwent()
- OVAL: Filter all non-interactive shells: /sbin/nologin, /usr/sbin/nologin,
  /bin/false, /usr/bin/false (previously only filtered nologin shells)
- Bash: Use getent passwd instead of /etc/passwd to query all users
- Bash: Replace awk system() call with native bash loop to prevent command
  injection (variables are now properly quoted)
- Bash: Use underscore (_) for unused passwd fields to fix shellcheck warnings
- Bash: Filter out all non-interactive shells
- Ansible: Filter out non-interactive shells using rejectattr
- Rule: Update description, OCIL, and fixtext to reference getent passwd
  and clarify remote user support
- Macro: Update create_interactive_users_list_object to exclude /bin/false
  and /usr/bin/false shells (affects all rules using this macro)

Security: The bash remediation previously used awk's system() function without
proper quoting, which could allow command injection if an attacker controlled
passwd entries. The new implementation uses a native bash while-read loop with
properly quoted variables and the -- separator to prevent both command and
flag injection.

(cherry picked from commit 9950f05)
@ggbecker ggbecker added this to the 0.1.82 milestone Aug 24, 2026
@ggbecker ggbecker changed the title Support remote users in file_groupownership_home_directories rule Stabilization: Support remote users in file_groupownership_home_directories rule Aug 24, 2026
@ggbecker ggbecker added RHEL Red Hat Enterprise Linux product related. STIG STIG Benchmark related. labels Aug 24, 2026
@Mab879 Mab879 self-assigned this Aug 24, 2026
@github-actions

Copy link
Copy Markdown

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

Click here to see the full diff
New content has different text for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_home_directories'.
--- xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
+++ xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
@@ -5,15 +5,19 @@
 All Interactive User Home Directories Must Be Group-Owned By The Primary Group
 
 [description]:
-Change the group owner of interactive users home directory to the
-group found in /etc/passwd. To change the group owner of
-interactive users home directory, use the following command:
+Change the group owner of interactive user home directories to the
+group found in getent passwd. To change the group owner of
+an interactive user's home directory, use the following command:
 $ sudo chgrp USER_GROUP /home/USER
         
 
 This rule ensures every home directory related to an interactive user is
-group-owned by an interactive user. It also ensures that interactive users
+group-owned by that user's primary group. It also ensures that interactive users
 are group-owners of one and only one home directory.
+
+Interactive users are those with a UID greater than or equal to 1000
+and a valid interactive shell (not /sbin/nologin, /usr/sbin/nologin,
+/bin/false, or /usr/bin/false).
 
 [warning]:
 Due to OVAL limitation, this rule can report a false negative in a

OCIL for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_home_directories' differs.
--- ocil:ssg-file_groupownership_home_directories_ocil:questionnaire:1
+++ ocil:ssg-file_groupownership_home_directories_ocil:questionnaire:1
@@ -1,5 +1,9 @@
 To verify the assigned home directory of all interactive users is group-
-owned by that users primary GID, run the following command:
-# ls -ld $(awk -F: '($3>=1000)&&($7 !~ /nologin/){print $6}' /etc/passwd)
+owned by that user's primary GID, run the following command:
+# ls -ld $(getent passwd | awk -F: '($3>=1000)&&($7 !~ /nologin/)&&($7 !~ /\/false$/){print $6}')
+
+This should return a list of home directories with group ownership matching each user's primary group.
+Using getent passwd instead of reading /etc/passwd directly ensures that remote users
+(LDAP, SSSD, NIS, etc.) are also checked.
       Is it the case that the group ownership is incorrect?
       
bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_home_directories' differs.
--- xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
+++ xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
@@ -1,2 +1,12 @@
 
-awk -F':' '{ if ($3 >= 1000 && $3 != 65534 && $6 != "/") system("chgrp -f " $4" "$6) }' /etc/passwd
+# Get interactive users using getent to support remote users (LDAP, SSSD, etc.)
+while IFS=: read -r _ _ uid gid _ home shell; do
+    # Filter interactive users: UID >= 1000, not nobody, has valid home dir, not nologin/false shell
+    if [ "$uid" -ge 1000 ] && [ "$uid" -ne 65534 ] && \
+       [ "$home" != "/" ] && \
+       [ "$shell" != "/sbin/nologin" ] && [ "$shell" != "/usr/sbin/nologin" ] && \
+       [ "$shell" != "/bin/false" ] && [ "$shell" != "/usr/bin/false" ]; then
+        # Arguments are properly quoted to prevent command injection
+        chgrp -f -- "$gid" "$home"
+    fi
+done < <(getent passwd)

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_groupownership_home_directories' differs.
--- xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
+++ xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
@@ -1,4 +1,4 @@
-- name: Get all local users from /etc/passwd
+- name: Get all users from getent to support remote users (LDAP, SSSD, etc.)
   ansible.builtin.getent:
     database: passwd
     split: ':'
@@ -12,9 +12,12 @@
   - no_reboot_needed
   - restrict_strategy
 
-- name: Create local_users variable from the getent output
+- name: Create interactive_users variable filtering out non-interactive shells
   ansible.builtin.set_fact:
-    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
+    interactive_users: '{{ ansible_facts.getent_passwd|dict2items|rejectattr("value.5",
+      "match", ".*/sbin/nologin$")|rejectattr("value.5", "match", ".*/usr/sbin/nologin$")|rejectattr("value.5",
+      "match", ".*/bin/false$")|rejectattr("value.5", "match", ".*/usr/bin/false$")|list
+      }}'
   tags:
   - CCE-83434-1
   - DISA-STIG-RHEL-08-010740
@@ -30,7 +33,7 @@
   ansible.builtin.stat:
     path: '{{ item.value[4] }}'
   register: path_exists
-  loop: '{{ local_users }}'
+  loop: '{{ interactive_users }}'
   when:
   - item.value[1]|int >= 1000
   - item.value[1]|int != 65534
@@ -45,12 +48,11 @@
   - no_reboot_needed
   - restrict_strategy
 
-- name: Ensure interactive local users are the group-owners of their respective home
-    directories
+- name: Ensure interactive 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 }}'
+  loop: '{{ interactive_users|zip(path_exists.results)|list }}'
   when: item.1.stat is defined and item.1.stat.exists
   tags:
   - CCE-83434-1

@Mab879
Mab879 merged commit ef45a76 into ComplianceAsCode:stabilization Aug 25, 2026
57 of 58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RHEL Red Hat Enterprise Linux product related. STIG STIG Benchmark related.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants