How to reset var folder permissions and ownership to their default in Debian

If by accident you execute a command that changes the permission or ownership of a bunch of folders or file in Debian, you are in a lot of trouble, usually the sollution is to reinstall the system, but as I was unwilling to reinstall thet system, I decided to find another way to do it, as I have finally set up my system as I want it to run, so we will look into a couple of methods of how to do it without reinstallation of the system.

Using virtual machine, reinstalling packages, or even generating a script from debian packages.

I accidently ran a chown command on the whole /var folder, and ended up with every file and folder in ownership of www-data.

According to the manual the var directory is:

The /var directory is mostly mounted as a separate filesystem under the root where in all the variable content like logs, spool files for printers, crontab,at jobs, mail, running process, lock files etc. Care has to be taken in planning this file system and maintenance as this can fill up pretty quickly and when the FileSystem is full can cause system and application operational issues.

I wanted to chown all the hidden files in the directory /var/www to www-data, I was in the directory /var/www when I ran the following command

chown -R www-data:www-data .*

And after running this, I noticed that my whole var folder was in ownership of www-data, so my quest to restore it to the original ownership and permissions started.

Imagine if it was rm instead of chown, I would have ended up deleting all the files in the var folder.

If you ever what to do something with the hidden files you should use the following approach, what I should have written should have been:

chown -R /var/www/.[^.]*

This command properly sets the hidden folders to the correct owners

So now I ended up with a var folder with a lot of messed up ownerships, so how to restore them.

There are multiple ways to do it, although the only way to completly restore them as they were would require you to deploy on a virtual machine, and copy the properties, that is the surest way so they are restored correctly

Method 1: Virtual Machine

Start installing you distribution on the virtual machine, and while you are waiting for the instalation to finish you need to prepeare some data needed for restoration of your machine.

This doesn’t have to happen on your machine, you can easily create a virtual machine on any computer and use the data to restore your own.

All the commands here are run as root.

We need a list of all your installed packages so they can be restored on the virtual machine, to get them, execute the following command

dpkg --get_selections > selections.txt

By now the machine should have finished installing, so let’s prepare some of the necessities, I use a pinning and a lot of repositores, including testing, unstable, stable, plus 3rd party repositories, so to do so we need to transfer the contents of /etc/apt to the virtual machine, you should know how to transfer the files to the virtual machine.

We also need to transfer the keys, because you can’t copy the keys we need to export them.

apt-key exportall > keys.gpg

And then transfer them to the virtual machine, and run the import for keys

apt-key add keys.gpg

If you are using multiarch you will have to add the appropriate architecture into the system, in my case I’m using also i386 libraries for skype, so I executed this on my virtual machine

dpkg --add-architecture i386

Now we need to install all the packages that are on our system, so let’s run the following commands on the virtual machine

apt-get update
dselect update
dpkg --set-selections < selections.txt

Now you can leave your virtual machine for a while, while it downloads all the packages and installs them.

After the installation has finished you can reboot your system, and after it boots, we need to extract all the information so we can restore it successfully.

On the virtual machine run the following command:

find /var -printf "%m:%u:%g:%p\n" > /tmp/var.permissions.txt

Now you transfer the generated file /tmp/var.permissions.txt to your machine, and you run the following script to restore everything as it was

#!/bin.bash
while IFS=":" read perms user group file; do 
chmod -R $perms $file > /dev/null 2>&1
chown -R $user:$group $file > /dev/null 2>&1
done < /tmp/var.permissions.txt

This is one way to restore them and it’s probably the best way to restore them

FreeBSD

If you have FreeBSD you can use mtree to copy over the permissions and restore them, the first line creates a list of the permissions and owners the second one restores them

mtree -c -k uname,gname,mode,time > /tmp/var.permissions.txt
mtree -U -f /tmp/var.permissions.txt

Method 2: From the debian packages

You can also restore permissions from the debian packages, but not the owners, as it doesn’t contain that information, it will restore them to how they are suppose to be when installing them the first time, but the permissions will be restored correctly.’

There are two ways to do this, you can restore them from the debian cache which is located in /var/cache/apt/archives/, but if you ever issued apt-get clean you will not have all the packages there, or you can just download all the packages and restore them like that, the script will be the same for both approaches.

So let’s create a new folder in opt, called restore

mkdir -p /opt/restore

I called my script create_permissions_script.sh, and I put it in /opt/restore, it is designed to work from the local directory the script is in.

This script reads all the packages, extracts the file list including permissions and owners, parses it and then stores it in a file so you can restore it.

#!/bin/bash
# /opt/restore/create_permissions_script.sh
ARCHIVE_DIR=`pwd`
PACKAGES=`ls $ARCHIVE_DIR/*.deb`
cd $ARCHIVE_DIR

cd /

function changePerms()
{
  CHOWN="/bin/chown"
  CHMOD="/bin/chmod"
  PERMS=`echo $1 | sed -e 's/--x/1/g' -e 's/-w-/2/g' -e 's/-wx/3/g' -e 's/r--/4/g' -e 's/r-x/5/g' -e 's/rw-/6/g' -e 's/rwx/7/g' -e 's/---/0/g'` 
  FTYPE=`echo ${PERMS:0:1}`
  PERMS=`echo ${PERMS:1}`
  OWN=`echo $2 | /usr/bin/tr '/' '.'`
  PATHNAME=$3
  PATHNAME=`echo ${PATHNAME:1}`
 
  if [[ "d" = "$FTYPE" ]]; then
    echo "$CHOWN -R $OWN $PATHNAME" >> "${ARCHIVE_DIR}/dir_perms.sh"
    echo "$CHMOD $PERMS $PATHNAME" >> "${ARCHIVE_DIR}/dir_perms.sh"
  else
    echo "$CHOWN $OWN $PATHNAME" >> "${ARCHIVE_DIR}/file_perms.sh"
    echo "$CHMOD $PERMS $PATHNAME" >> "${ARCHIVE_DIR}/file_perms.sh"
  fi;

  #fi;
}

for PACKAGE in $PACKAGES;
do
  if [ -d $PACKAGE ]; then
    continue;
  fi
  echo "Getting information for $PACKAGE"
  FILES=`/usr/bin/dpkg -c "${PACKAGE}"`
  for FILE in "$FILES";
  do
    echo "$FILE" | awk '{print $1"\t"$2"\t"$6}' | while read line;
    do
      changePerms $line
    done
  done
done

sort "${ARCHIVE_DIR}/dir_perms.sh" | uniq > "${ARCHIVE_DIR}/clean_dir_perms.sh"
sort "${ARCHIVE_DIR}/file_perms.sh" | uniq > "${ARCHIVE_DIR}/clean_file_perms.sh"

cat "${ARCHIVE_DIR}/clean_dir_perms.sh" "${ARCHIVE_DIR}/clean_file_perms.sh" > "${ARCHIVE_DIR}/restore_permissions.sh"
rm "${ARCHIVE_DIR}/clean_dir_perms.sh" "${ARCHIVE_DIR}/clean_file_perms.sh" "${ARCHIVE_DIR}/dir_perms.sh" "${ARCHIVE_DIR}/file_perms.sh"

This script will generate a new script called restore_permissions.sh, which contains all the neccesseary commands like chown and chmod for all the directories and files, executing this script will correct all the ownerships and permissions as they need to be after installation of the package in question

So let’s download the packages, or if you choose to restore them from the cache folder you can skip this step, just copy over this script to the cache folder and you are done, if you are like me and you ocasionally clean up the folder, you will have to download all the packages first

dpkg --get-selections \* | awk '{print $1}' | xargs -l1 apt-get download 

Executing that line will download all the packages into the directory, as this will take a while, you can take a break.

After all the packages finish downloading, you need to run the script for generating the permissions and owners, this will also take a while to read and process all debian packages

./create_permissions_script.sh

After this is finished you will see that you have a script called restore_permissions.sh, and running it will restore the permissions

./restore_permissions.sh

Method 3: Reinstalling with aptitude

You can reinstall all the packages using aptitude, but this is a really slow process, but if you want to you can do like so

dpkg --get-selections \* | awk '{print $1}' | xargs -l1 aptitude reinstall