Anyone know of a script, program, etc... to check folder/file permissions and repair/restore?
I am not a newb. I am a professional imploring to other professionals over their discoveries of a quick solution to a common problem, and I know what chmod -R
is.
This is in response to the -1 rating instantly given to my question, for those who might shrug off the seriousness of my inquiry, or dismiss its validity.
Experimenting with sshfs between my desktop and a remote server running Kali linux as root (Default for Kali). Managed to bugger up all file & folder permissions/ownership on the system. I have managed to repair some, with a simple chmod -R 0755
where appropriate, but have noticed many are still not fixed.
Wondering if there is a bash script or other script or program that could help to restore the correct owner & permissions?
I have found a similar script, but it is primarily aimed at repairing home directories.
Script, Below:
#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "Processing ..."
find -H $(pwd) -type d -exec chmod 0755 {} \;
# set dirs to 755
find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
# libs
IFS=$'\n'
for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
if [ -z "$tstbin" ]; then
tstbat=$(cat "$value" | head -c2 | grep -io '#!')
if [ -n "$tstbat" ]; then
perm=$(stat -c '%a' "$value")
if [ "$perm" != "755" ]; then
chmod 755 $value
echo "Set script 755 $value"
# set batch to 755
fi
else
perm=$(stat -c '%a' "$value")
if [ "$perm" != "644" ]; then
chmod 644 $value
echo "Set regular 644 $value"
# set regular files to 644
fi
fi
# above aren't elf binary
else
perm=$(stat -c '%a' "$value")
if [ "$perm" != "755" ]; then
chmod 755 $value
echo "Set binary 755 $value"
# set elf binaries to 755
fi
fi
done
unset IFS
# process linux permissions for files and folders
else
echo "Aborted."
fi
Anyone found anything more substantial that can fix permissions and ownership for a file system?
--> Update: <--
Not discovering a desirable solution, I have taken to modifying the above script and making it facilitate my desired resolution:
permafix.sh - Gist on github
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# ====================================================================
# --> Documentation <--
# ---------------------
#
# 0755 21 root root .
# 0755 21 root root ..
# 0755 2 root root bin
# 0755 4 root root boot
# 0755 15 root root dev
# 0755 53 root root etc
# 0755 4 root root home
# 0755 7 root root lib
# 0700 2 root root lost+found
# 0755 6 root root media
# 0755 2 root root mnt
# 0755 4 root root opt
# dr-xr-xr-x 87 root root proc # Not touching this.
# 0744 8 root root root
# 0755 2 root root sbin
# 0755 3 root root share
# 0755 4 root root srv
# 0755 12 root root sys
# 1777 7 root root tmp
# 0755 12 root root usr
# 0755 13 root root var
#
# ========================================================================
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "Processing ..."
#################
# Special Cases #
#################
SDIR=("/lost+found" "/root" "/tmp")
for sd in ${SDIR[-1]}; do
perm=$(stat -c '%a' "$sd")
user=$(stat -c '%U' "$sd")
group=$(stat -c '%G' "$sd")
if [ $sd = "/tmp" ]; then
if [ "$perm" != 1777 ]; then
chmod 1777 $sd
echo "Set directory to 177 $sd"
fi
elif [ $sd = "/lost+found" ]; then
if [ "$perm" != 0700 ]; then
chmod 0700 $sd
echo "Set directory to 0700 $sd"
fi
elif [ $sd = "/root" ]; then
if [ "$perm" != 744 ];then
chmod 744 $sd
echo "Set directory to 744 $sd"
fi
else
echo "Abort!"
fi
# Do change in ownership
if [ "$user" != root ]; then
chown root $sd
echo "Set user to root $sd"
fi
if [ "$group" != root ]; then
chgrp root $sd
echo "Set group to root $sd"
fi
done
###############
# Directories #
###############
DIR=("/bin" "/boot" "/dev" "/etc" "/home" "/lib" "/media" "/mnt" "/opt" "/sbin" "/share" "/srv" "/sys" "/usr" "/var")
for pd in ${DIR[-1]}; do
perm=$(stat -c '%a' "$pd")
user=$(stat -c '%U' "$pd")
group=$(stat -c '%G' "$pd")
if [ "$perm" != 755 ]; then
chmod 755 $pd
echo "Set directory to 755 $pd"
fi
if [ "$user" != root ]; then
chown root $pd
echo "Set user to root $pd"
fi
if [ "$group" != root ]; then
chgrp root $pd
echo "Set group to root $pd"
fi
############################
# Subdirectories and files #
############################
# chmod directories to 755
find -H $pd -type d -exec chmod 0755 {} \;
# Check library files
find -H $pd -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
done
#------#
# libs #
#------#
# Assign Variables
LIBFILES=$(find -H "$(pwd)" -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n')
# Now do the hustle
for PLF in $LIBFILES; do
tstbin=$(readelf -l "$PLF" 2>/dev/null | grep -Pio 'executable|shared')
if [ -z "$tstbin" ]; then
tstbat=$(cat "$PLF" | head -c2 | grep -io '#!')
if [ -n "$tstbat" ]; then
perm=$(stat -c '%a' "$PLF")
if [ "$perm" != "755" ]; then
chmod 755 $PLF
echo "Set script 755 $PLF"
# set batch to 755
fi
else
perm=$(stat -c '%a' "$PLF")
if [ "$perm" != "644" ]; then
chmod 644 $PLF
echo "Set regular 644 $PLF"
# set regular files to 644
fi
fi
# above aren't elf binary
else
perm=$(stat -c '%a' "$PLF")
if [ "$perm" != "755" ]; then
chmod 755 $PLF
echo "Set binary 755 $PLF"
# set elf binaries to 755
fi
fi
done
unset IFS
# process linux permissions for files and folders
else
# When shit goes pear shaped
echo "Aborted."
fi
There are other ways of doing this, and also better ways to write the code. But, it works for now.
--->Yet another update<---
I fixed a careless error in the script correctly relocation the position of several variables that were formerly inaccessible due to script structure.
Please use this link to acquire the most recent version of this script.
A simple script to fix arbitrary broken permissions on a general purpose system does not exist. You, your users, and the software you use can set whatever permissions you like to meet your requirements. Overly broad permission changes are a loss of that metadata.
First, determine how permissions were broken, for example chmod
chown
setfacl
or chcon
commands. If ownership is wrong, you'll need to fix that, such as giving a file in a home directory back to its owner. Beware there are subtle things here, like chown will clear setuid flags. For example, /usr/bin/ping might not work, if it loses setuid root. Do you know which other of your programs need setuid? More complex ACLs or selinux labels are not in your solution, but could complicate things if they also are wrong.
You can attempt to fix permissions to what they were on package install. On Debian based systems, you might feed dpkg --contents
output into a chmod chown script. Downloading .debs for all installed packages for dpkg to query is an exercise for the reader. This does nothing for user data, or software not installed via deb.
Identify sensitive information previously protected by file permissions. Including but not limited to ssh and gpg private keys. Consider changing these credentials out of an abundance of caution.
Regarding the rest of user data, hard to say. Users generally, but not always, own files in their home directories. Multiple user shared directories could get tricky, as the correct owner and mode might no longer be known.
Backups should restore with correct permissions, if they existed.
Tedious work to fix correctly. Document by writing automation scripting that fixes permissions on your data directories. Hopefully backups will fix things next time, but might as well have policy on what the permissions should be.