Linux – Fix permissions of server after accidental chmod debian

debianfile-permissionslinuxpermissions

in my panic i posted to ubuntu forum by mistake, im reposting in the correct place (i think)

While trying to debug a mail server, I typed:

chmod -R 777 /

instead of:

chmod -R 777 .

and the icing on the cake, due to me forgetting I had changed a script I use to sign in to fix something, I did all this as root. I do not have backups of most of the system (poor choice I know).

Unlike in the questions "Recovering from chmod -R -777 /" and "What to do after 'chmod -R 777 /'?" i am still signed in as root, and not the whole system was changed, so I do have some control over the system. I also ^C d out of the command within one second to minimize damage. Since then I have physically disconnected the server from the internet.

I believe a script could fix it if it restored the permissions of the filesystem based on data from the package manager, but i do not know how I would go about doing this. If this is not possible, how would I save the data from the server to reinstall the OS?

I am aware of the potential risks of missing a file, but would prefer recovery to reinstall despite them.

this is the current output of ls -la /:

drwxrwxrwx  22 root root  4096 Sep  7  2016 .
drwxrwxrwx  22 root root  4096 Sep  7  2016 ..
drwxr-xr-x   2 root root  4096 May 18 07:55 bin
drwxr-xr-x   3 root root  4096 Sep 21 07:53 boot
drwxr-xr-x  19 root root  3180 Sep 11 20:54 dev
drwxrwxrwx  92 root root  4096 Aug 23 07:50 etc
drwxr-xr-x   4 root root  4096 May 23  2016 home
lrwxrwxrwx   1 root root    31 Feb 24  2016 initrd.img -> /boot/initrd.img-3.16.0-4-amd64
drwxrwxrwx  18 root root  4096 Feb 24  2016 lib
drwxr-xr-x   2 root root  4096 Jun 20 07:00 lib64
drwx------   2 root root 16384 May 19  2016 lost+found
drwxrwxrwx   2 root root  4096 May  5  2015 media
drwxr-xr-x   2 root root  4096 May  5  2015 mnt
drwxr-xr-x   3 root root  4096 May 28  2016 opt
dr-xr-xr-x 148 root root     0 Sep  3 21:55 proc
drwxrwxrwx  10 root root  4096 Aug 19 17:58 root
drwxr-xr-x  22 root root   800 Sep 21 17:09 run
drwxrwxrwx   3 root root  4096 Jun 20 07:00 sbin
drwxr-xr-x   4 root root  4096 Sep 20 23:18 sftp
dr-xr-xr-x  13 root root     0 Sep  3 21:55 sys
drwxrwxrwx   8 root root  4096 Sep 21 17:17 tmp
drwxrwxrwx  11 root root  4096 Feb 24  2016 usr
drwxr-xr-x  14 root root  4096 Jun 25 06:21 var
lrwxrwxrwx   1 root root    27 Feb 24  2016 vmlinuz -> boot/vmlinuz-3.16.0-4-amd64

im aware thats not how you fix a mail server. it was a hacky sloppy fix to see what broke. trust me, im not going to do that again

Best Answer

If this is a system you have physical access to, you could just mount its drive on to another running, working system and at the very least copy any data you want to save off of it. This is probably the safest and most reliable means of recovery of just the data itself.

You could also find the permissions of a working system (ideally of the exact same OS version and with the exact same packages installed on it) and change the permissions of the broken system to match it -- again, this is most easily done if you can mount the broken system's drive on to a working system, but it might also be possible to do if the system is remote and you can still ssh in to it, become root and chmod.

Note: Before doing anything, I recommend doing a full backup of the broken system (again, this is most easily done if you have physical access to it). If anything goes wrong, make a fresh copy from your backup and try again on the copy, keeping your original backup untouched so it can be restored from again if there's another mistake.

On the working system, you should be able to create a null-separated list of files and working permissions like this:

# find / -name '*' -printf '%m %p\0' > working-permissions.txt

Sidenote: It's null-separated because it's most likely you don't have any filenames with nulls in them, so it's safer to separate them like this rather than using newlines (you still aren't likely to have filenames with newlines in them, but better safe than sorry, and null-separation is safer).

Take a look at the output of xargs --null -n1 --arg-file=working-permissions.txt echo | less to make sure the permissions and filenames look sane. If they do, you now have a choice of ways to proceed:

Option 1:

If you can still log in to the broken system and can become root, you could try copying the working-permissions.txt file to the broken system and when logged in to the broken system run:

# perl -0ne '$_ =~ m{^(\d*\d\d\d) (.*)\0$} ; print "chmod $1 $2\n" ; chmod oct($1), $2 ;' working-permissions.txt

Option 2:

You could mount the disk from the broken system on to the working system. Now you will need to change the perl command above to reflect where you've mounted it. For example, if you've mounted it on /mnt/broken, you'd do:

# perl -0ne '$_ =~ m{^(\d*\d\d\d) (.*)\0$} ; print "chmod $1 $2\n" ; chmod oct($1), "/mnt/broken/$2" ;' working-permissions.txt

The perl script will now change permissions in /mnt/broken.

Note: Option 2 is actually more dangerous to the working system (in case there's a mistake in the script). So when you're ready to run the perl script to change permissions, I suggest you use a LiveDVD or USB drive to first boot the working system, and don't have any drives except the broken system's drive connected to it.

Finally, once you've got your broken system working again, make frequent backups so that if any catastrophe hits it again, you'll be able to just restore from backup and move on.

Related Question