Blob Blame History Raw
From 5ec53805a4aaf04752400eef826ff49222c0a3ba Mon Sep 17 00:00:00 2001
From: Marcus Burghardt <maburgha@redhat.com>
Date: Wed, 20 Oct 2021 16:17:01 +0200
Subject: [PATCH 1/3] OVAL, tests and remediation for the rule:

accounts_user_interactive_home_directory_defined
---
 .../ansible/shared.yml                        | 24 +++++++++++++
 .../bash/shared.sh                            |  9 +++++
 .../oval/shared.xml                           | 36 +++++++++++++++++++
 .../tests/home_dir_all_empty.fail.sh          |  6 ++++
 .../tests/home_dir_not_exclusive.fail.sh      |  6 ++++
 .../tests/home_dir_one_empty.fail.sh          |  8 +++++
 .../tests/home_dir_properly_defined.pass.sh   |  4 +++
 .../tests/home_dir_root.fail.sh               |  6 ++++
 .../tests/interactive_users_absent.pass.sh    |  4 +++
 9 files changed, 103 insertions(+)
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/oval/shared.xml
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_all_empty.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_not_exclusive.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_one_empty.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_properly_defined.pass.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_root.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/interactive_users_absent.pass.sh

diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
new file mode 100644
index 00000000000..fc9b780daa8
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
@@ -0,0 +1,24 @@
+# platform = multi_platform_all
+# reboot = false
+# strategy = restrict
+# complexity = low
+# disruption = low
+
+- name: Get all local users from /etc/passwd
+  ansible.builtin.getent:
+    database: passwd
+    split: ':'
+
+- name: Create local_users variable from the getent output
+  ansible.builtin.set_fact:
+    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
+
+- name: Ensure interactive users have a home directory defined
+  ansible.builtin.user:
+    name: '{{ item.key }}'
+    home: '/home/{{ item.key }}'
+    create_home: no
+  loop: '{{ local_users }}'
+  when:
+    - item.value[2]|int >= {{{ uid_min }}}
+    - item.value[2]|int != 65534
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
new file mode 100644
index 00000000000..23b0a85aa6a
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
@@ -0,0 +1,9 @@
+# platform = multi_platform_all
+# reboot = false
+# strategy = restrict
+# complexity = low
+# disruption = low
+
+for user in `awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1 }' /etc/passwd`; do
+    sed -i "s/\($user:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\/home\/$user\2/g" /etc/passwd;
+done
\ No newline at end of file
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/oval/shared.xml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/oval/shared.xml
new file mode 100644
index 00000000000..5efb84ab2cf
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/oval/shared.xml
@@ -0,0 +1,36 @@
+<def-group>
+  <definition class="compliance" id="{{{ rule_id }}}" version="1">
+    {{{ oval_metadata("All Interactive Users Must Have A Home Directory Defined") }}}
+    <criteria>
+      <criterion test_ref="test_accounts_user_interactive_home_directory_defined"
+                 comment="All Interactive Users Must Have A Home Directory Defined"/>
+    </criteria>
+  </definition>
+
+  <!-- For detailed comments about logic used in this OVAL, check the
+       "file_ownership_home_directories" rule.
+       #### creation of object #### -->
+  <unix:password_object id="object_accounts_user_interactive_home_directory_defined_objects"
+                        version="1">
+    <unix:username datatype="string" operation="not equal">nobody</unix:username>
+    <filter action="include">state_accounts_user_interactive_home_directory_defined_uids</filter>
+  </unix:password_object>
+
+  <unix:password_state id="state_accounts_user_interactive_home_directory_defined_uids"
+                       version="1">
+    <unix:user_id datatype="int" operation="greater than or equal">{{{ uid_min }}}</unix:user_id>
+  </unix:password_state>
+
+  <!-- #### creation of state #### -->
+  <unix:password_state id="state_accounts_user_interactive_home_directory_defined" version="1">
+    <unix:home_dir operation="pattern match">^\/\w*\/\w{1,}[\/\w]*$</unix:home_dir>
+  </unix:password_state>
+
+  <!-- #### creation of test #### -->
+  <unix:password_test id="test_accounts_user_interactive_home_directory_defined" check="all"
+                      check_existence="any_exist" version="1"
+                      comment="All Interactive Users Have A Home Directory Defined">
+    <unix:object object_ref="object_accounts_user_interactive_home_directory_defined_objects"/>
+    <unix:state state_ref="state_accounts_user_interactive_home_directory_defined"/>
+  </unix:password_test>
+</def-group>
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_all_empty.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_all_empty.fail.sh
new file mode 100644
index 00000000000..4bc9e10a21c
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_all_empty.fail.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M $USER
+
+sed -i "s/\(.*:x:[0-9]\{4,\}:[0-9]*:.*:\).*\(:.*\)$/\1\2/g" /etc/passwd
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_not_exclusive.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_not_exclusive.fail.sh
new file mode 100644
index 00000000000..5c905e03791
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_not_exclusive.fail.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M $USER
+
+sed -i 's/\(.*:x:[0-9]\{4,\}:[0-9]*:.*:\).*\(:.*\)$/\1\/tmp\2/g' /etc/passwd
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_one_empty.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_one_empty.fail.sh
new file mode 100644
index 00000000000..00d37799c77
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_one_empty.fail.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+USER1="cac_user1"
+USER2="cac_user2"
+useradd -M $USER1
+useradd -M $USER2
+
+sed -i "s/\($USER1:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\2/g" /etc/passwd
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_properly_defined.pass.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_properly_defined.pass.sh
new file mode 100644
index 00000000000..7c181afdd4b
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_properly_defined.pass.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M $USER
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_root.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_root.fail.sh
new file mode 100644
index 00000000000..16bb94477bc
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_root.fail.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M $USER
+
+sed -i "s/\($USER:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\/\2/g" /etc/passwd
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/interactive_users_absent.pass.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/interactive_users_absent.pass.sh
new file mode 100644
index 00000000000..ed34f0940a7
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/interactive_users_absent.pass.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# remove all interactive users (ID >= 1000) from /etc/passwd
+sed -i '/.*:[0-9]\{4,\}:/d' /etc/passwd

From 47cf69c176ce8e7ec1922bf8cdcd1d35b02552c9 Mon Sep 17 00:00:00 2001
From: Marcus Burghardt <maburgha@redhat.com>
Date: Tue, 26 Oct 2021 14:39:11 +0200
Subject: [PATCH 2/3] OVAL, tests and remediation for the rule:

accounts_user_interactive_home_directory_exists
---
 .../bash/shared.sh                            |  2 +-
 .../ansible/shared.yml                        | 24 +++++
 .../bash/shared.sh                            |  9 ++
 .../oval/shared.xml                           | 91 +++++++++++++++++++
 .../tests/home_dir_present.pass.sh            | 10 ++
 .../tests/home_dirs_all_absent.fail.sh        |  6 ++
 .../tests/home_dirs_one_absent.fail.sh        |  7 ++
 .../tests/interactive_users_absent.pass.sh    |  4 +
 8 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/bash/shared.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/oval/shared.xml
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dir_present.pass.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_all_absent.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_one_absent.fail.sh
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/interactive_users_absent.pass.sh

diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
index 23b0a85aa6a..94f8a579f1f 100644
--- a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
@@ -6,4 +6,4 @@
 
 for user in `awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1 }' /etc/passwd`; do
     sed -i "s/\($user:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\/home\/$user\2/g" /etc/passwd;
-done
\ No newline at end of file
+done
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
new file mode 100644
index 00000000000..e7acc477d25
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
@@ -0,0 +1,24 @@
+# platform = multi_platform_all
+# reboot = false
+# strategy = restrict
+# complexity = low
+# disruption = low
+
+- name: Get all local users from /etc/passwd
+  ansible.builtin.getent:
+    database: passwd
+    split: ':'
+
+- name: Create local_users variable from the getent output
+  ansible.builtin.set_fact:
+    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
+
+- name: Ensure interactive users have a home directory defined
+  ansible.builtin.user:
+    name: '{{ item.key }}'
+    home: '/home/{{ item.key }}'
+    create_home: yes
+  loop: '{{ local_users }}'
+  when:
+    - item.value[2]|int >= {{{ uid_min }}}
+    - item.value[2]|int != 65534
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/bash/shared.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/bash/shared.sh
new file mode 100644
index 00000000000..044b650f103
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/bash/shared.sh
@@ -0,0 +1,9 @@
+# platform = multi_platform_all
+# reboot = false
+# strategy = restrict
+# complexity = low
+# disruption = low
+
+for user in $(awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1}' /etc/passwd); do
+    mkhomedir_helper $user 0077;
+done
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/oval/shared.xml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/oval/shared.xml
new file mode 100644
index 00000000000..0a5b313f5b4
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/oval/shared.xml
@@ -0,0 +1,91 @@
+<def-group>
+  <definition class="compliance" id="{{{ rule_id }}}" version="1">
+    {{{ oval_metadata("All Interactive Users Home Directories Must Exist") }}}
+    <criteria operator="OR">
+      <criterion test_ref="test_accounts_user_interactive_home_directory_exists"
+                 comment="All Interactive Users Home Directories Must Exist"/>
+      <criterion test_ref="test_accounts_user_interactive_home_directory_exists_users"
+                 comment="Interactive users don't exist on the system"/>
+    </criteria>
+  </definition>
+
+  <!-- #### prepare a password object for the two tests in this rule #### -->
+  <unix:password_object id="object_accounts_user_interactive_home_directory_exists_objects"
+                        version="1">
+    <unix:username datatype="string" operation="not equal">nobody</unix:username>
+    <filter action="include">state_accounts_user_interactive_home_directory_exists_uids</filter>
+  </unix:password_object>
+
+  <unix:password_state id="state_accounts_user_interactive_home_directory_exists_uids" version="1">
+    <unix:user_id datatype="int" operation="greater than or equal">{{{ uid_min }}}</unix:user_id>
+  </unix:password_state>
+
+  <!-- #### create a local variable composed by the list of home dirs from /etc/passwd #### -->
+  <local_variable id="var_accounts_user_interactive_home_directory_exists_dirs_list"
+                  datatype="string" version="1"
+                  comment="Variable including all home dirs from interactive users">
+    <object_component item_field="home_dir"
+                      object_ref="object_accounts_user_interactive_home_directory_exists_objects"/>
+  </local_variable>
+
+  <!-- #### create a local variable composed by the number of home dirs from /etc/passwd #### -->
+  <local_variable id="var_accounts_user_interactive_home_directory_exists_dirs_count"
+                  datatype="int" version="1"
+                  comment="Variable including expected count of home dirs present on the system">
+    <count>
+      <variable_component var_ref="var_accounts_user_interactive_home_directory_exists_dirs_list"/>
+    </count>
+  </local_variable>
+
+  <!-- #### create a file_object to check existence of home dirs on file system #### -->
+  <unix:file_object id="object_accounts_user_interactive_home_directory_exists_dirs_fs"
+                    version="1">
+    <unix:path var_ref="var_accounts_user_interactive_home_directory_exists_dirs_list"
+               var_check="at least one"/>
+    <unix:filename xsi:nil="true"/>
+  </unix:file_object>
+
+  <!-- #### create a local variable with the number of home dirs present on file system #### -->
+  <local_variable id="var_accounts_user_interactive_home_directory_exists_dirs_count_fs"
+                  datatype="int" version="1"
+                  comment="Variable including number of home dirs present on file system">
+    <count>
+      <object_component item_field="path"
+                  object_ref="object_accounts_user_interactive_home_directory_exists_dirs_fs"/>
+    </count>
+  </local_variable>
+
+  <!-- #### create a variable object with count of home dirs from file system #### -->
+  <ind:variable_object id="object_accounts_user_interactive_home_directory_exists_dirs_count_fs"
+                       version="1">
+    <ind:var_ref>var_accounts_user_interactive_home_directory_exists_dirs_count_fs</ind:var_ref>
+  </ind:variable_object>
+
+  <!-- #### create a variable state with count of home dirs from /etc/passwd #### -->
+  <ind:variable_state id="state_accounts_user_interactive_home_directory_exists_dirs_count_pw"
+                      version="1">
+    <ind:value datatype="int" operation="equals" var_check="at least one"
+               var_ref="var_accounts_user_interactive_home_directory_exists_dirs_count"/>
+  </ind:variable_state>
+
+  <!-- #### test_accounts_user_interactive_home_directory_exists #### -->
+  <ind:variable_test id="test_accounts_user_interactive_home_directory_exists" check="all"
+                     check_existence="at_least_one_exists" version="1"
+                     comment="Check the existence of interactive users.">
+    <ind:object object_ref="object_accounts_user_interactive_home_directory_exists_dirs_count_fs"/>
+    <ind:state state_ref="state_accounts_user_interactive_home_directory_exists_dirs_count_pw"/>
+  </ind:variable_test>
+
+  <!-- #### create of variable object with count of home dirs from /etc/passwd #### -->
+  <ind:variable_object id="object_accounts_user_interactive_home_directory_exists_dirs_count_pw"
+                       version="1">
+    <ind:var_ref>var_accounts_user_interactive_home_directory_exists_dirs_count</ind:var_ref>
+  </ind:variable_object>
+
+  <!-- #### test_accounts_user_interactive_home_directory_exists_users #### -->
+  <ind:variable_test id="test_accounts_user_interactive_home_directory_exists_users" check="all"
+                     check_existence="none_exist" version="1"
+                     comment="Check the existence of interactive users.">
+    <ind:object object_ref="object_accounts_user_interactive_home_directory_exists_dirs_count_pw"/>
+  </ind:variable_test>
+</def-group>
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dir_present.pass.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dir_present.pass.sh
new file mode 100644
index 00000000000..d5434cbe4f5
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dir_present.pass.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -m $USER
+
+# This is to make sure that any possible user create in the test environment has also
+# a home dir created on the system.
+for user in $(awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1}' /etc/passwd); do
+    mkhomedir_helper $user 0077;
+done
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_all_absent.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_all_absent.fail.sh
new file mode 100644
index 00000000000..af240252de3
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_all_absent.fail.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M $USER
+# This make sure home dirs related to test environment users are also removed.
+rm -Rf /home/*
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_one_absent.fail.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_one_absent.fail.sh
new file mode 100644
index 00000000000..5bce517215c
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/home_dirs_one_absent.fail.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+USER1="cac_user1"
+USER2="cac_user2"
+
+useradd -m $USER1
+useradd -M $USER2
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/interactive_users_absent.pass.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/interactive_users_absent.pass.sh
new file mode 100644
index 00000000000..ed34f0940a7
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/tests/interactive_users_absent.pass.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# remove all interactive users (ID >= 1000) from /etc/passwd
+sed -i '/.*:[0-9]\{4,\}:/d' /etc/passwd

From 0d6a5e588d71e927291641cbf2a23259995f0b2d Mon Sep 17 00:00:00 2001
From: Marcus Burghardt <maburgha@redhat.com>
Date: Mon, 8 Nov 2021 15:09:12 +0100
Subject: [PATCH 3/3] Improved the remediation and rule description

Included conditional on remediation to make sure that
already compliant home directories are skipped.
---
 .../ansible/shared.yml                                     | 3 ++-
 .../bash/shared.sh                                         | 7 +++++--
 .../rule.yml                                               | 5 +++++
 .../tests/home_dir_defined_out_home.pass.sh                | 4 ++++
 .../ansible/shared.yml                                     | 3 +--
 5 files changed, 17 insertions(+), 5 deletions(-)
 create mode 100644 linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_defined_out_home.pass.sh

diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
index fc9b780daa8..13fbdd1ca44 100644
--- a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/ansible/shared.yml
@@ -13,7 +13,7 @@
   ansible.builtin.set_fact:
     local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
 
-- name: Ensure interactive users have a home directory defined
+- name: Ensure interactive users have an exclusive home directory defined
   ansible.builtin.user:
     name: '{{ item.key }}'
     home: '/home/{{ item.key }}'
@@ -22,3 +22,4 @@
   when:
     - item.value[2]|int >= {{{ uid_min }}}
     - item.value[2]|int != 65534
+    - not item.value[4] | regex_search('^\/\w*\/\w{1,}')
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
index 94f8a579f1f..7fac61d4892 100644
--- a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/bash/shared.sh
@@ -4,6 +4,9 @@
 # complexity = low
 # disruption = low
 
-for user in `awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1 }' /etc/passwd`; do
-    sed -i "s/\($user:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\/home\/$user\2/g" /etc/passwd;
+for user in $(awk -F':' '{ if ($4 >= {{{ uid_min }}} && $4 != 65534) print $1 }' /etc/passwd); do
+    # This follows the same logic of evaluation of home directories as used in OVAL.
+    if ! grep -q $user /etc/passwd | cut -d: -f6 | grep '^\/\w*\/\w\{1,\}'; then
+        sed -i "s/\($user:x:[0-9]*:[0-9]*:.*:\).*\(:.*\)$/\1\/home\/$user\2/g" /etc/passwd;
+    fi
 done
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/rule.yml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/rule.yml
index 20d26032338..b58164c5403 100644
--- a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/rule.yml
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/rule.yml
@@ -8,6 +8,11 @@ description: |-
     Assign home directories to all interactive users that currently do not
     have a home directory assigned.
 
+    This rule checks if the home directory is properly defined in a folder which has
+    at least one parent folder, like "user" in "/home/user" or "/remote/users/user".
+    Therefore, this rule will report a finding for home directories like <tt>/users</tt>,
+    <tt>/tmp</tt> or <tt>/</tt>.
+
 rationale: |-
     If local interactive users are not assigned a valid home directory, there is no
     place for the storage and control of files they should own.
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_defined_out_home.pass.sh b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_defined_out_home.pass.sh
new file mode 100644
index 00000000000..c7100f304ca
--- /dev/null
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_defined/tests/home_dir_defined_out_home.pass.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+USER="cac_user"
+useradd -M -d /data/$USER $USER
diff --git a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
index e7acc477d25..84382a7f488 100644
--- a/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
+++ b/linux_os/guide/system/accounts/accounts-session/accounts_user_interactive_home_directory_exists/ansible/shared.yml
@@ -13,10 +13,9 @@
   ansible.builtin.set_fact:
     local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
 
-- name: Ensure interactive users have a home directory defined
+- name: Ensure interactive users have a home directory exists
   ansible.builtin.user:
     name: '{{ item.key }}'
-    home: '/home/{{ item.key }}'
     create_home: yes
   loop: '{{ local_users }}'
   when: