Reversing some /usr/local damage

Solution 1:

As for the first part of your question, you can't revert the changes, there's no Z or undo command, but you can set the permissions to a good guess of what it was before. More on this in the first bullet below.

To install software in /usr/local you must have write permissions in the directory (and its subdirectories). There are several ways to achieve this:

  1. Set the owner to yourself. That's what you did with sudo chown -R $USER /usr/local. My Linux sysadmin background tells me this is not the standard way, because /usr/local is outside your home directory and shouldn't be owned by you. But I wouldn't say you damaged anything irreparably.
  2. Use sudo, but you don't want to be required to use it.

    (From my point of view the best solution. Why? sudo protects you from yourself. You think twice if you need to type sudo (unless you are following a tutorial from http://howtonode.org :-) ).)

  3. Set ACLs. Nice way to separate the original permissions from your added permissions. (See http://en.wikipedia.org/wiki/Access_control_list for more info on ACLs.)
  4. Configure groups. Add yourself to the group that owned /usr/local and change permissions to g+rwx/g+rw. Cumbersome. Don't do that.

You did 1. and want to revert the changes, 2. you don't want, and I don't recommend 4., so I'll explain 3.:

  • Let's first "revert" the changes you made. /usr/local was probably owned by user root, group wheel. You can set it as follows:

    $ cd /usr/local
    $ sudo chown -R root:wheel .
    
  • Set the ACLs so that you have all permissions:

    $ cd /usr/local
    $ sudo chmod -R +a "$USER allow delete,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown,list,search,add_file,add_subdirectory,delete_child,file_inherit,directory_inherit" .
    

    (see man chmod, section ACL MANIPULATION OPTIONS for details.)

  • You will see that all files have a + appended, ls -e shows the ACLs:

    $ cd /usr/local
    $ ls -la .
    total 0
    drwxr-xr-x+ 11 root  wheel   374 Oct 10 21:57 .
    drwxr-xr-x+ 12 root  wheel   442 Sep 22 13:44 ..
    drwxr-xr-x+  3 root  wheel  3774 Oct 10 21:57 bin
    -rw-r--r--+  1 jaume wheel    0  Oct 25 14:53 myACLtestfile
    drwxr-xr-x+  3 root  wheel   136 Jul 26 18:55 include
    drwxr-xr-x+  4 root  wheel   442 Jul 26 18:55 lib
    (...)
    $ ls -led bin
    drwxr-xr-x+ 3 root  wheel  3774 Oct 10 21:57 bin
     0: user:jaume allow list,add_file,search,delete,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown,file_inherit,directory_inherit
    $ ls -le myACLtestfile 
    -rw-r--r--+ 1 jaume  wheel  0 Oct 25 14:53 myACLtestfile
     0: user:jaume inherited allow read,write,execute,delete,append,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown
    

(I've tested the commands above, but I may have made a typo. As best practice I recommend that you run the commands above in a test directory. You could do mkdir ~/tmpacl. Then cd ~/tmpacl and sudo rsync -av /usr/local/ . to copy the contents of /usr/local to ~/tmpacl. Then skip cd /usr/local in every section above to apply the commands to ~/tmpacl. When you are done, rm -rf ~/tmpacl.)

Now you can install software (or do anything, for that matter) in /usr/local without sudo.

Notice that any file you create in /usr/local will belong to you (as myACLtestfile in the listing above), so you will see that some files are owned by root and others by you.

(If you change your mind and want to go back to the wonderful world of sudo, delete the ACLs as follows:

sudo chmod -R -N /usr/local

and set permissions to root:wheel:

sudo chown -R root:wheel /usr/local

)


** EDIT **

If the setup routine of the software you want to install uses /usr/bin/install this may be a much simpler solution. Add:

alias install="sudo /usr/bin/install"

to ~/.bashrc. Then do . ~/.bashrc for changes to take effect.

Then edit /etc/sudoers with command sudo visudo, add:

<your username> ALL=(ALL) NOPASSWD:/usr/bin/install

and save and close the file with :x.

(If you use other install command elsewhere in the filesystem, like GNU install, change the path above appropriately.)

For this to work the software must use /usr/bin/install. This is usually the case with make install.

** /EDIT **

Solution 2:

Boot to your recovery HD and see whether you want to use terminal to fix the Mac HD /usr/local by hand or if you'd rather just restore from a convenient backup.

Since Macs don't need anything to exist in /usr/local I don't see how sudo or anything system critical is even affected so perhaps I am not even understanding your situation.

Remove everything from /usr/local and start over is often a good plan for your local command-line content to get set up properly if you can’t clean/repair it piecemeal.