Locked Files in Mac OS X
I spend a lot of my time in the Mac OS X terminal (well, iTerm 2), and I'm at home with many of the command-line Unixy conventions. With that comfort also comes a high expectation that things will work in a specific way. This past week I've been manually restoring files from a Time Machine backup. Surprises ensued.
You may observe files with the correct ownership (chown) and
permissions (chmod u+rw) that are write-locked. In my experience, the
files were editable with sudo, and modification via the Finder would
prompt for an administrator password. In these situations, you may be
dealing with additional file attributes.
Access Control Lists (ACLs)
Your file may have an ACL that prevents writing by the current user. To
view ACLs for a file, issue ls -le. Use chmod to modify ACLs. Run
chmod -N to remove the ACL.
File Flags
Running "Get Info..." on a file and checking "Locked" is functionally
equivalent to running chflags uchg [file]. Show flags in directory
listings using ls -lO. See also: SetFile.
Extended Attributes (metadata)
For good measure, we should also mention extended attributes.
xattr modifies attributes (xattr -r -c to recursively remove), and
ls -l@ will display attributes.
I don't know of any specific metadata that would prevent file modification.
All Together, Now
annika@fsck:~:0$ mkdir /tmp/foo && cd /tmp/foo && touch bar
annika@fsck:/tmp/foo:0$ xattr -w com.sixohthree.test "o hai" bar
annika@fsck:/tmp/foo:0$ chmod +a 'everyone deny write,append,delete' bar
annika@fsck:/tmp/foo:0$ chflags uchg bar
annika@fsck:/tmp/foo:0$ ls -le@O
total 0
-rw-r--r--@ 1 adam  wheel  uchg 0 Dec  8 09:18 bar
        com.sixohthree.test     5  0: group:everyone deny write,delete,append
The uchg flag will prevent all file modifications, including changing
ACLs and extended attributes.
annika@fsck:/tmp/foo:0$ date >> bar
-bash: bar: Operation not permitted
annika@fsck:/tmp/foo:1$ chflags nouchg bar
annika@fsck:/tmp/foo:0$ date >> bar
-bash: bar: Operation not permitted
annika@fsck:/tmp/foo:1$ chmod -N bar
annika@fsck:/tmp/foo:0$ date >> bar
annika@fsck:/tmp/foo:0$