84 lines
2.3 KiB
Bash
Executable File
84 lines
2.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Log file for tracking changes
|
|
LOGFILE="/var/log/fix-ownership.log"
|
|
echo "Starting ownership change process on $(date)" > "$LOGFILE"
|
|
|
|
# Cache to track unchanged users and groups
|
|
UNCHANGED_USERS=()
|
|
UNCHANGED_GROUPS=()
|
|
USER_EXISTS=false
|
|
GROUP_EXISTS=false
|
|
|
|
# function to check if a user is unchanged
|
|
is_user_unchanged() {
|
|
local user="$1"
|
|
[[ " ${UNCHANGED_USERS[@]} " =~ " ${user} " ]]
|
|
}
|
|
|
|
# function to check if a group is unchanged
|
|
is_group_unchanged() {
|
|
local group="$1"
|
|
[[ " ${UNCHANGED_GROUPS[@]} " =~ " ${group} " ]]
|
|
}
|
|
|
|
# function to process a single file
|
|
process_file() {
|
|
local filepath="$1"
|
|
|
|
# gather username, UID, group name, and GID of the file/folder
|
|
FILE_UID=$(stat -c "%u" "$filepath")
|
|
FILE_GID=$(stat -c "%g" "$filepath")
|
|
FILE_USER=$(stat -c "%U" "$filepath")
|
|
FILE_GROUP=$(stat -c "%G" "$filepath")
|
|
|
|
# skip files owned by unchanged users and groups
|
|
if is_user_unchanged "$FILE_USER" && is_group_unchanged "$FILE_GROUP"; then
|
|
return
|
|
fi
|
|
|
|
# check if the user exists in /lib/passwd
|
|
if grep -q "^${FILE_USER}:" /lib/passwd; then
|
|
EXPECTED_UID=$(getent passwd "$FILE_USER" | cut -d: -f3)
|
|
USER_EXISTS=true
|
|
fi
|
|
|
|
# check if the group exists in /lib/group
|
|
if grep -q "^${FILE_GROUP}:" /lib/group; then
|
|
EXPECTED_GID=$(getent group "$FILE_GROUP" | cut -d: -f3)
|
|
GROUP_EXISTS=true
|
|
fi
|
|
|
|
# compare UID
|
|
if $USER_EXISTS then
|
|
if [[ "$FILE_UID" != "$EXPECTED_UID" ]]; then
|
|
echo "Fixing UID for $filepath: $FILE_UID -> $EXPECTED_UID" >> "$LOGFILE"
|
|
chown "$EXPECTED_UID" "$filepath"
|
|
else
|
|
# mark user as unchanged
|
|
UNCHANGED_USERS+=("$FILE_USER")
|
|
fi
|
|
fi
|
|
|
|
# compare GID
|
|
if $GROUP_EXISTS then
|
|
if [[ "$FILE_GID" != "$EXPECTED_GID" ]]; then
|
|
echo "Fixing GID for $filepath: $FILE_GID -> $EXPECTED_GID" >> "$LOGFILE"
|
|
chgrp "$EXPECTED_GID" "$filepath"
|
|
else
|
|
# mark group as unchanged
|
|
UNCHANGED_GROUPS+=("$FILE_GROUP")
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
export -f process_file
|
|
export LOGFILE
|
|
export UNCHANGED_USERS
|
|
export UNCHANGED_GROUPS
|
|
|
|
# Parallelized processing with find and xargs
|
|
find / -path /sysroot -prune -o -print 2>/dev/null | xargs -P "$(nproc)" -I {} bash -c 'process_file "$@"' _ {}
|
|
echo "ownership chnage process completed on $(date)" >> "$LOGFILE"
|