Thursday, July 06, 2006

chflags, Immutable files, Securelevel, Single-User Mode

It's often useful to mark a file as "immutable", requiring even the superuser to take some additional action before the file can be modified. Under Linux's ext2/3 filesystem this is implemented through the "attributes" commands (chattr, lsattr), using the immutable attribute. Under Windows, the "attrib" command provides similar functionality by allowing you to mark files as read-only.

Under Mac OS X, files can be marked immutable by using the "chflags" command. Chflags provides a way to attach several extended attributes (or "flags") to files and directories. Available flags are (from the man page):
arch    set the archived flag (root only)
opaque set the opaque flag (owner or root only)
nodump set the nodump flag (owner or root only)
sappnd set the system append-only flag (root only)
schg set the system immutable flag (root only)
sunlnk set the system undeletable flag (root only)
uappnd set the user append-only flag (owner or root only)
uchg set the user immutable flag (owner or root only)
uunlnk set the user undeletable flag (owner or root only)
There are also several aliases, such as "archived" for "arch". Each of the flags can be unset by prepending "no" (e.g., "nouchg" is the opposite of "uchg"). Flags set by chflags can be viewed with "ls -lo".

Chflags actually provides two slightly different "immutable" flags: uchg and schg. There are two differences between these flags. First, only the superuser can set the schg flag, but the uchg flag can also be set by a file's owner. Second (and perhaps more important), even the superuser may be unable to un-set the schg flag, depending on the current securelevel of the system.

Mac OS X inherits the concept of securelevel from BSD. The idea is that the kernel contains a variable called "securelevel". At boot time, securelevel has a value of 0, but this can be changed later. Once the securelevel has been raised, it cannot be lowered (even by the superuser) without a reboot. When Mac OS X goes into multi-user mode, it sets the value of securelevel to 1. You can see this with the "sysctl" command:
sysctl kern.securelevel
Going back to the immutable flags, the schg flag differs from the uchg flag in that schg cannot be unset unless the operating system is in securelevel 0. This means that if you set the schg flag on a file, you won't be able to unset it without booting into single-user mode (in which securelevel is still 0). You can boot into single-user mode by holding down the "command" (funky apple octothorpe/clover symbol) and "s" keys while booting.

No comments: