Debian – Fix broken permissions on /var (or any other system directory)

debianpermissionssystem-recovery

Long story short, I destroyed /var and restored it from backup – but the backup didn't have correct permissions set, and now everything in /var is owned by root. This seems to make a few programs unhappy.

I've since fixed apt failing fopen on /var/cache/man as advised here as well as apache2 failing to start (by giving ownership of /var/lib/apache2 to www-data). However, right now the only way to fix everything seems to be to manually muck around with permissions as problems arise – this seems very difficult as I would have to wait for a program to start giving problems, establish that the problem is related to permissions of some files in /var and then set them right myself.

Is there an easy way to correct this? I already tried reinstalling (plain aptitude reinstall x) every package that was listed in dpkg -S /var, but that didn't work.

Best Answer

Actually apt-get --reinstall install package should work, with files at least:

➜  ~  ls -l /usr/share/lintian/checks/version-substvars.desc        
-rw-r--r-- 1 root root 2441 Jun 22 14:19 /usr/share/lintian/checks/version-substvars.desc
➜  ~  sudo chmod +x /usr/share/lintian/checks/version-substvars.desc
➜  ~  ls -l /usr/share/lintian/checks/version-substvars.desc        
-rwxr-xr-x 1 root root 2441 Jun 22 14:19 /usr/share/lintian/checks/version-substvars.desc
➜  ~  sudo apt-get --reinstall install lintian  
(Reading database ... 291736 files and directories currently installed.)
Preparing to unpack .../lintian_2.5.27_all.deb ...
Unpacking lintian (2.5.27) over (2.5.27) ...
Processing triggers for man-db (2.6.7.1-1) ...
Setting up lintian (2.5.27) ...
➜  ~  ls -l /usr/share/lintian/checks/version-substvars.desc
-rw-r--r-- 1 root root 2441 Jun 22 14:19 /usr/share/lintian/checks/version-substvars.desc

Now, you probably didn't get all the packages that have files on your /var directory, so its better to find them all:

➜  ~ find /var -exec dpkg -S {} + 2> /dev/null | grep -v "no path found" | wc -l 
460

In my case, it accounts for 460 paths that have a package, this is actually less if you consider that the same package can have several paths, which with some post processing we can find out that are ~122:

➜  ~  find /var -exec dpkg -S {} + 2> /dev/null | grep -v "no path found" | cut -d : -f 1 | sort | uniq | wc -l
122

This of course counts several package that has the same path, like wamerican, aspell-en, ispanish, wspanish, aspell-es, myspell-es. This is easily fixable:

➜  ~  find /var -exec dpkg -S {} + 2> /dev/null | grep -v "no path found" | cut -d : -f 1 | sed 's/, /\n/g' | sort | uniq | wc -l
107

So, I have 107 package that have any kind of file in /var or subdirectories. You can reinstall them using:

sudo apt-get --reinstall install $(find /var -exec dpkg -S {} + 2> /dev/null | grep -v "no path found" | cut -d : -f 1 | sed 's/, /\n/g')

This should fix the permissions.

Now, there's another option, find a good installation and copy the file permissions over your installation with:

chmod --recursive --reference good/var bad/var
Related Question