In the previous part, Managing System File Permissions was completed.
1. CIS Benchmark Requirements (Section 7.2)
This article examines the integrity of identity-related files, prevention of UID/GID conflicts, and securing users' home directories:
- 7.2.1 Ensure accounts in /etc/passwd use shadowed passwords (Automated)
- 7.2.2 Ensure /etc/shadow password fields are not empty (Automated)
- 7.2.3 Ensure all groups in /etc/passwd exist in /etc/group (Automated)
- 7.2.4 Ensure no duplicate UIDs exist (Automated)
- 7.2.5 Ensure no duplicate GIDs exist (Automated)
- 7.2.6 Ensure no duplicate user names exist (Automated)
- 7.2.7 Ensure no duplicate group names exist (Automated)
- 7.2.8 Ensure local interactive user home directories are configured (Automated)
- 7.2.9 Ensure local interactive user dot files access is configured (Automated)
2. Concept and Rationale
The integrity of identity files such as passwd and group is critical for system security. Using shadowed passwords ensures that password hashes are not stored in /etc/passwd. Duplicate UID or GID values can lead to access conflicts. In addition, proper configuration of home directories and hidden files (dot files) helps prevent unauthorized manipulation of the user environment.
3. Oracle Database Compatibility Review (RAC & Grid)
The requirements in this section are purely operating system integrity checks and do not interfere with Oracle users and groups. In clustered environments (RAC), strict UID/GID consistency across all nodes, especially for controls 7.2.4 through 7.2.7, is one of the core prerequisites for Oracle installation. Therefore, compliance with these controls helps ensure not only security, but also database infrastructure stability.
4. Auditing the Current State (Audit Script)
The following script checks the integrity of identity files, the existence of empty passwords, and the status of home directories.
The GitHub path of this script is: modules/audit_29_Local_User_Group_Settings.sh
If you are not familiar with Bash scripting, you may refer to the training provided for database administrators on the site: Bash for Oracle DBAs
#!/bin/bash
# -------------------------------------------------------------------------
# Script: audit29.sh
# Purpose: Audit Local User and Group Settings (CIS 7.2)
# -------------------------------------------------------------------------
echo "=========================================================================="
echo " CIS Requirement: 7.2 - Local User and Group Settings"
echo " - 7.2.1: Ensure accounts in /etc/passwd use shadowed passwords."
echo " - 7.2.2: Ensure /etc/shadow does not contain empty password fields."
echo " - 7.2.4: Ensure no duplicate UIDs exist."
echo " - 7.2.5: Ensure no duplicate GIDs exist."
echo " - 7.2.6: Ensure no duplicate user names exist."
echo " - 7.2.7: Ensure no duplicate group names exist."
echo " - 7.2.8/9: Ensure home directory and dot-file permissions are secure."
echo ""
echo " Oracle Context & Exceptions:"
echo " - Fully Compatible. UID/GID consistency is a PRE-REQUISITE for Oracle"
echo " RAC / Grid Infrastructure installations."
echo ""
echo " Action Taken:"
echo " - This script audits all the CIS requirements listed above."
echo "=========================================================================="
echo ""
FAILED=0
# --- Audit Checks ---
echo "[*] Auditing: Non-shadowed passwords (CIS 7.2.1)..."
NON_SHADOWED=$(awk -F: '($2 != "x" ) { print $1 }' /etc/passwd)
if [ -n "$NON_SHADOWED" ]; then
echo "[-] FAIL: Accounts found without shadowed passwords: $NON_SHADOWED"
FAILED=1
else
echo "[+] PASS: All accounts use shadowed passwords."
fi
echo -e "\n[*] Auditing: Empty password fields (CIS 7.2.2)..."
EMPTY_PASS=$(awk -F: '($2 == "" ) { print $1 }' /etc/shadow)
if [ -n "$EMPTY_PASS" ]; then
echo "[-] FAIL: Accounts with empty passwords found: $EMPTY_PASS"
FAILED=1
else
echo "[+] PASS: No empty password fields found."
fi
echo -e "\n[*] Auditing: Duplicate UIDs (CIS 7.2.4)..."
DUP_UIDS=$(cut -f3 -d":" /etc/passwd | sort -n | uniq -c | awk '$1 > 1 {print $2}')
if [ -n "$DUP_UIDS" ]; then
echo "[-] FAIL: Duplicate UIDs found:"
for uid in $DUP_UIDS; do
users=$(awk -F: '($3 == n) { print $1 }' n=$uid /etc/passwd | xargs)
echo " -> UID $uid is shared by: $users"
done
FAILED=1
else
echo "[+] PASS: No duplicate UIDs found."
fi
echo -e "\n[*] Auditing: Duplicate GIDs (CIS 7.2.5)..."
DUP_GIDS=$(cut -f3 -d":" /etc/group | sort -n | uniq -c | awk '$1 > 1 {print $2}')
if [ -n "$DUP_GIDS" ]; then
echo "[-] FAIL: Duplicate GIDs found:"
for gid in $DUP_GIDS; do
groups=$(awk -F: '($3 == n) { print $1 }' n=$gid /etc/group | xargs)
echo " -> GID $gid is shared by: $groups"
done
FAILED=1
else
echo "[+] PASS: No duplicate GIDs found."
fi
echo -e "\n[*] Auditing: Duplicate user names (CIS 7.2.6)..."
DUP_USERS=$(cut -d: -f1 /etc/passwd | sort | uniq -c | awk '$1 > 1 {print $2}')
if [ -n "$DUP_USERS" ]; then
echo "[-] FAIL: Duplicate Usernames found: $DUP_USERS"
FAILED=1
else
echo "[+] PASS: No duplicate user names found."
fi
echo -e "\n[*] Auditing: Duplicate group names (CIS 7.2.7)..."
DUP_GROUPS=$(cut -d: -f1 /etc/group | sort | uniq -c | awk '$1 > 1 {print $2}')
if [ -n "$DUP_GROUPS" ]; then
echo "[-] FAIL: Duplicate Group Names found: $DUP_GROUPS"
FAILED=1
else
echo "[+] PASS: No duplicate group names found."
fi
echo -e "\n[*] Auditing: Home directory permissions (CIS 7.2.8 & 7.2.9)..."
HOME_ISSUES=0
awk -F: '($3 >= 1000 && $1 != "nfsnobody") { print $1 " " $6 }' /etc/passwd | while read -r user dir; do
if [ -d "$dir" ]; then
dirperm=$(stat -L -c "%a" "$dir")
# Using 8# to explicitly tell bash these are octal numbers
if [ $(( 8#$dirperm & 8#022 )) -ne 0 ]; then
echo "[-] FAIL: Home directory ($dir) for user ($user) is group or world-writable ($dirperm)."
HOME_ISSUES=1
fi
fi
done
if [ "$HOME_ISSUES" -eq 0 ]; then
echo "[+] PASS: Interactive user home directory permissions are secure."
else
FAILED=1
fi
# --- Final Result ---
echo "=========================================================================="
if [ "$FAILED" -eq 1 ]; then
echo "[!] FINAL AUDIT RESULT: FAILED. Remediation required."
else
echo "[+] FINAL AUDIT RESULT: PASSED."
fi
echo "=========================================================================="
5. Applying the Settings (Remediation Bash Script)
Resolving UID and GID conflicts requires manual review by the system administrator, but actions such as enabling password shadowing and locking accounts with empty passwords can be performed automatically.
The GitHub path of this script is: modules/remediate_29_Local_User_Group_Settings.sh
#!/bin/bash
# Script: remediate_cis_7_2.sh
# Purpose: Remediate obvious issues in Local User Settings
if [ "$EUID" -ne 0 ]; then echo "Please run as root"; exit 1; fi
echo -e "\n[+] Remediating CIS 7.2..."
echo "[*] Ensuring shadowed passwords (pwconv)..."
pwconv
echo "[*] Locking accounts with empty passwords..."
for user in $(awk -F: '($2 == "" ) { print $1 }' /etc/shadow); do
echo "Locking account $user due to empty password."
passwd -l "$user"
done
echo "[*] Fixing permissions on interactive user home directories..."
awk -F: '($3 >= 1000 && $1 != "nfsnobody") { print $1 " " $6 }' /etc/passwd | while read -r user dir; do
if [ -d "$dir" ]; then
chmod g-w,o-rwx "$dir"
# Securing dot files
find "$dir" -type f -name ".*" -exec chmod go-w {} \; 2>/dev/null
fi
done
echo "[+] Automated remediation applied."
echo "[!] Action Required: Duplicate UIDs, GIDs, and Usernames must be resolved manually."
Our work in this series concludes here.
If you have any comments on the scripts, please let me know so the necessary corrections can be applied.