How to repair/restore ubuntu 10.04 after 'sudo chmod / 777'
Solution 1:
You're looking at a lost cause. Save the data you need, and reinstall the operating system.
Solution 2:
I know dpkg stores the permissions in the databases and I found the following script google which may help.
Edit: I actually had a quick look at the script and it looks as if it is missing a bit of magic that goes from PERMS to MODE eg dpkg -c gives for example "-rw-r--r--" but you want 0644, I am at work right now so I am not sure I have the time to do the conversion at this instant but I may come back later if no one else has jumped in to add that bit.
There is a script here which is looks interesting
#!/bin/bash
# Restores file permissions for all files on a debian system for which .deb
# packages exist.
#
# Author: Larry Kagan <me at larrykagan dot com>
# Since 2007-02-20
ARCHIVE_DIR=/var/cache/apt/archives/
PACKAGES=`ls $ARCHIVE_DIR`
cd /
function changePerms()
{
CHOWN="/bin/chown"
CHMOD="/bin/chmod"
PERMS=$1
OWN=`echo $2 | /usr/bin/tr '/' ':'`
PATHNAME=$3
echo -e "$CHOWN $OWN $PATHNAME"
#`$CHOWN $OWN $PATHNAME`
#`$CHMOD $MODE $PATHNAME`
}
for PACKAGE in $PACKAGES;
do
echo -e "Getting information for $PACKAGE\n"
FILES=`/usr/bin/dpkg -c "${ARCHIVE_DIR}${PACKAGE}"`
for FILE in "$FILES";
do
FILE_DETAILS=`echo "$FILE" | awk '{print $1"\t"$2"\t"$6}'`
changePerms $FILE_DETAILS
done
done
Solution 3:
It is possible to come back from such a messy situation, without reinstalling the system. Well, more exactly running a fresh new system either from an USB key or in a Virutal Box (or so) if you have a dual boot system.
I ran again the same kind on issue (some bug in a script I was writing) and solved it, but you need to ask some expert's help. Be very cautuous!
First, my situation was easier to solve because I had a dual boot system (ubuntu and my old fedora install), but running the system for a USB key (or maybe a CD/DVD) should do the same thing.
MPOINT=/mount/ubuntu
First I mounted my file systems like this (don't forget to create the mount points): mount /dev/ubuntu/root $MPOINT mount /dev/ubuntu/home $MPOINT/home
Then I ran the following command (my issue was only in a few - critical - directories) to copy the permissions on from the running system to the messy one (in fact, in my case, I installed an ubuntu system in Virtual Box under fedora and got the permissions there):
find /etc /usr /bin -exec stat --format "chmod %a ${MPOINT}%n" {} \; > /tmp/restoreperms.sh
And then I ran the restoreperms.sh script.
I was able again to boot on ubuntu.
The content of restoreperms.sh will be something like:
(...)
chmod 755 /mount/ubuntu//etc/ppp
chmod 755 /mount/ubuntu//etc/ppp/ipv6-up
chmod 2750 /mount/ubuntu//etc/ppp/peers
chmod 640 /mount/ubuntu//etc/ppp/peers/provider
chmod 755 /mount/ubuntu//etc/ppp/ipv6-up.d
chmod 777 /mount/ubuntu//etc/ppp/resolv.conf
(...)
I didn't test it but it must work for owners and owner groups too. Something like:
find /etc /usr /bin -exec stat --format 'chown %U:%G ${MPOINT}%n' {} \; > /tmp/restoreperms.sh^
(...)
chown root:root /mount/ubuntu//etc/obex-data-server/imaging_capabilities.xml
chown root:root /mount/ubuntu//etc/obex-data-server/capability.xml
chown root:dip /mount/ubuntu//etc/ppp
chown root:root /mount/ubuntu//etc/ppp/ipv6-up
chown root:dip /mount/ubuntu//etc/ppp/peers
chown root:dip /mount/ubuntu//etc/ppp/peers/provider
chown root:root /mount/ubuntu//etc/ppp/ipv6-up.d
chown root:root /mount/ubuntu//etc/ppp/resolv.conf
(...)
Of course, you have to take care here, that the UID and GID are the same on both systems, but for the system related users and groups, this shouldn't be an issue.
Rk:
An important thing for this is to keep an install disk synchronized with the version you are using, or at least work with the current ubuntu version. Now, I have this commands in a cronjob, running every day (could be weeks) in order to keep that information. It will make the solution easier next time but, of course, as I have this now, it will never happen again. ;-) Something like this:
0 12 * * * /usr/bin/find / -exec /usr/bin/stat --format="/bin/chmod %a %n" {} \; |/bin/bzip2 -c > /tmp/restore_chmod.$(/bin/date +%w).sh.bz2
0 13 * * * /usr/bin/find / -exec /usr/bin/stat --format="/bin/chown %U:%G %n" {} \; |/bin/bzip2 -c > /tmp/restore_chown.$(/bin/date +%w).sh.bz2
EDIT: to support links, the combined command is:
/usr/bin/find / -exec /usr/bin/stat --format="[ ! -L {} ] && /bin/chmod %a %n" {}
Solution 4:
I modified the script from above and it's looks like this:
#!/bin/bash
# Restores file permissions for all files on a debian system for which .deb
# packages exist.
#
# Author: Larry Kagan <me at larrykagan dot com>
# Since 2007-02-20
ARCHIVE_DIR=/var/cache/apt/archives/
PACKAGES=`ls $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'`
PERMS=`echo ${PERMS:1}`
OWN=`echo $2 | /usr/bin/tr '/' '.'`
PATHNAME=$3
PATHNAME=`echo ${PATHNAME:1}`
# echo -e "CHMOD: $CHMOD $PERMS $PATHNAME"
# result=`$CHOWN $OWN $PATHNAME`
# if [ $? -ne 0 ]; then
# echo -e $result
# exit 123;
# fi
echo -e "CHOWN: $CHMOD $PERMS $PATHNAME"
result=`$CHMOD $PERMS $PATHNAME`
if [ $? -ne 0 ]; then
echo -e $result
fi
}
for PACKAGE in $PACKAGES;
do
if [ -d $PACKAGE ]; then
continue;
fi
echo -e "Getting information for $PACKAGE\n"
FILES=`/usr/bin/dpkg -c "${ARCHIVE_DIR}${PACKAGE}"`
for FILE in "$FILES";
do
#FILE_DETAILS=`echo "$FILE" | awk '{print $1"\t"$2"\t"$6}'`
echo "$FILE" | awk '{print $1"\t"$2"\t"$6}' | while read line;
do
changePerms $line
done
#changePerms $FILE_DETAILS
done
done