1

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=(&quot;/lost+found&quot; &quot;/root&quot; &quot;/tmp&quot;)
for sd in ${SDIR[-1]}; do
    perm=$(stat -c '%a' &quot;$sd&quot;)
    user=$(stat -c '%U' &quot;$sd&quot;)
    group=$(stat -c '%G' &quot;$sd&quot;)
    if [ $sd = &quot;/tmp&quot; ]; then
        if [ &quot;$perm&quot; != 1777 ]; then
            chmod 1777 $sd
            echo &quot;Set directory to 177 $sd&quot;
        fi
    elif [ $sd = &quot;/lost+found&quot; ]; then
        if [ &quot;$perm&quot; != 0700 ]; then
            chmod 0700 $sd
            echo &quot;Set directory to 0700 $sd&quot;
        fi
    elif [ $sd = &quot;/root&quot; ]; then
        if [ &quot;$perm&quot; != 744 ];then
            chmod 744 $sd
            echo &quot;Set directory to 744 $sd&quot;
        fi
    else
        echo &quot;Abort!&quot;
    fi
    # Do change in ownership
    if [ &quot;$user&quot; != root ]; then
        chown root $sd
        echo &quot;Set user to root $sd&quot;
    fi
    if [ &quot;$group&quot; != root ]; then
        chgrp root $sd
        echo &quot;Set group to root $sd&quot;
    fi
done
###############
# Directories #
###############
DIR=(&quot;/bin&quot; &quot;/boot&quot; &quot;/dev&quot; &quot;/etc&quot; &quot;/home&quot; &quot;/lib&quot; &quot;/media&quot; &quot;/mnt&quot; &quot;/opt&quot; &quot;/sbin&quot; &quot;/share&quot; &quot;/srv&quot; &quot;/sys&quot; &quot;/usr&quot; &quot;/var&quot;)
for pd in ${DIR[-1]}; do
    perm=$(stat -c '%a' &quot;$pd&quot;)
    user=$(stat -c '%U' &quot;$pd&quot;)
    group=$(stat -c '%G' &quot;$pd&quot;)
    if [ &quot;$perm&quot; != 755 ]; then
        chmod 755 $pd
        echo &quot;Set directory to 755 $pd&quot;
    fi
    if [ &quot;$user&quot; != root ]; then
        chown root $pd
        echo &quot;Set user to root $pd&quot;
    fi
    if [ &quot;$group&quot; != root ]; then
        chgrp root $pd
        echo &quot;Set group to root $pd&quot;
    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 &quot;$(pwd)&quot; -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 &quot;$PLF&quot; 2&gt;/dev/null | grep -Pio 'executable|shared')
    if [ -z &quot;$tstbin&quot; ]; then
        tstbat=$(cat &quot;$PLF&quot; | head -c2 | grep -io '#!')
        if [ -n &quot;$tstbat&quot; ]; then
            perm=$(stat -c '%a' &quot;$PLF&quot;)
            if [ &quot;$perm&quot; != &quot;755&quot; ]; then
                chmod 755 $PLF
                echo &quot;Set script 755 $PLF&quot;
                # set batch to 755
            fi
        else
            perm=$(stat -c '%a' &quot;$PLF&quot;)
            if [ &quot;$perm&quot; != &quot;644&quot; ]; then
                chmod 644 $PLF
                echo &quot;Set regular 644 $PLF&quot;
                # set regular files to 644
            fi
        fi
        # above aren't elf binary
    else
        perm=$(stat -c '%a' &quot;$PLF&quot;)
        if [ &quot;$perm&quot; != &quot;755&quot; ]; then
            chmod 755 $PLF
            echo &quot;Set binary 755 $PLF&quot;
            # 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.

Paul
  • 3,278

1 Answers1

2

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.

John Mahowald
  • 36,071