File ownership in Mac OS X is based directly on the underlying BSD Unix layer and inherits its strengths (as well as a few quirks) from that legacy. On Unix systems, a file has two owners: a user and a group. Each of these owners is separate from the other; there’s no requirement that a user who owns a file be a member of the group that owns that same file. This split in ownership is intended to let you be as flexible as possible in the way that you structure access to files. By allowing groups as well as individual users to be associated with a file, you can give users access to an entire set of files simply by adding them to a group, and you can take away access just as easily.
You can see the owner and group for a file in the Finder using the File → Get Info (-I) menu and unfolding the Ownership & Permissions section and the Details subsection, as shown in Figure 8-4. The Inspector tells you what the owner of a file, the users in the group that owns the file, and everybody else can do with the file. In the case of this image file, jldera
can both read and write to the file (which makes sense), and only members of the group jldera
can read the files, while everyone else cannot access the file.
Since the file ownership model in Mac OS X comes from Unix, it follows that there is a way to view these permissions
from the command line. Example 8-7 shows the use of the ls
command to view the ownership details for the contents of the Winter
directory (as seen in Figure 8-4).
Example 8-7. A file listing of the Winter directory
$ ls -la
total 9968
drwxr-xr-x 10 jldera jldera 340 Apr 16 16:23 .
drwxr-xr-x 13 jldera jldera 442 Apr 17 01:34 ..
-rw-r----- 1 jldera jldera 769018 Jul 2 2003 earlyfrost1600.jpg
-rw-r----- 1 jldera jldera 510003 Jul 2 2003 firstsnow1600.jpg
-rw-r----- 1 jldera jldera 340212 Jul 2 2003 polaris1600.jpg
-rw-r----- 1 jldera jldera 776794 Jul 2 2003 sleepingforest1600.jpg
-rw-r----- 1 jldera jldera 261422 Jul 2 2003 snowtop1600.jpg
-rw-r----- 1 jldera jldera 952634 Jul 2 2003 snowy1600.jpg
-rw-r----- 1 jldera jldera 773818 Jul 2 2003 valley11600.jpg
-rw-r----- 1 jldera jldera 706650 Jul 2 2003 valley2k1600.jpg
The first letter denotes the file type. In most cases, this will be either a hyphen (-) for a file or a d for a directory.
The next three letters (characters 2 through 4) indicate the permissions associated with the user owner of the file.
The next three letters (characters 5 through 7) indicate the permissions associated with the group owner of the file.
The last three letters (characters 8 through 10) indicate the permissions associated with everyone who is neither the file’s user nor a member of the group owner.
Each of the three letter groupings consists of either the letters r, w, and x, or the hyphen (-
) character. A letter indicates that permission is allowed, and a hyphen means the permission is withheld. Table 8-2 shows the meanings of these letters.
Table 8-2. File permissions characters
Letter |
Meaning for a directory |
Meaning for a file |
---|---|---|
|
Can list the contents of the directory. |
Can read the file. |
|
Can alter the contents of the directory. |
Can write to the file. |
|
Can make the directory the current directory (that is, |
Can be executed. |
|
The directory is "sticky" (see the discussion later in this section). | |
|
The executable is either Set UID or Set GID (see the discussion later in this section). |
Once you know the secret decoder to the string, it is pretty easy to read the permissions for a file or directory. Using this information, you can read the line describing firstsnow1600.jpg
in the file listing in Example 8-7 as follows:
We’re looking at a file.
The user jldera
has the ability to view and modify the contents of the file.
Members of the jldera
group can read the file as well, but not write to it.
No one else has access to the file.
The permissions for directories work in the same way. The key difference involves the execute bit. To work with the contents of a directory, you must have execute permissions for that directory. So in Figure 8-5, you can see that the jldera
user has read, write, and execute access to all of the folders. However, most of the folders only allow access to the jldera
user. The exceptions are Public and Sites. By the nature of their use, these two folders must be accessible by anyone. Thus their permissions have been set to allow read and execute permissions to all.
Table 8-3 shows the most common permission combinations and their meanings.
Table 8-3. Common file permission sets
Pattern |
Meaning |
Result |
---|---|---|
|
No access |
No activity allowed |
|
Read access only |
Lets users read the file |
|
Execute access only |
Lets users execute a program |
|
Read and execute access |
Lets users read and execute the file |
|
Write and execute access |
Lets users write to the file, but not read it; useful for Drop Boxes |
|
Full access |
Lets users read, write, and execute the file |
|
Read and write access |
Lets users read from and save to the file |
These permissions are reflected in Figure 8-6, which shows another user’s Finder view of jldera
’s Home directory. You can see the “Can’t Write” icon in the upper-left part of the window. You can also see that the Desktop, Documents, Library, Movies, Music, and Pictures folders have a “Do Not Enter” symbol on them, indicating that you can’t view their contents.
The sticky bit has an odd history. A long time ago it meant an executable file should be kept in memory even after the process using it exited. Most Unix implementations, including Mac OS X, don’t use it for this purpose anymore. But, somewhere along the way, it got coerced into another job. When the sticky bit is set on a directory, most file permissions still apply when attempting to read from or write to files within it. However, a user can delete only the files in the directory that belong to him, even if he has access rights to the directory because of a group membership.
For example, consider the /private/tmp
directory is used by Mac OS X and other Unixes for storing temporary files (though most other Unixes simply use /tmp
). Because the directory is used by many different users’ processes, the sticky bit is set on /private/tmp
to allow any user to write data to that folder. However, users may
only read from and write to the files they create in /private/tmp
. The sticky bit appears in a directory listing like this:
drwxrwxrwt 32 root wheel 1088 Apr 19 20:21 tmp
Notice the t
at the end of the permission sequence (drwxrwxrwt
). It indicates that the sticky bit has been set on the directory. Another directory that has the sticky bit set is /Users/Shared
, as shown in Example 8-8.
Example 8-8. A listing of the /Users directory
$ ls -la /Users
total 0
drwxrwxr-t 6 root admin 204 Apr 19 19:39 .
drwxrwxr-t 29 root admin 1088 Apr 16 20:48 ..
-rw-r—r-- 1 root wheel 0 Mar 20 18:57 .localized
drwxrwxrwt 6 root wheel 204 Apr 19 11:50 Shared
drwxr-xr-x 12 alisa alisa 408 Apr 19 19:46 alisa
drwxr-xr-x 16 jldera jldera 544 Apr 19 19:45 jldera
With the sticky bit set on/Users/Shared
, Mac OS X provides an easy way for users of the system to share files locally. Even though the folder is owned by root
, the sticky bit signals to the OS that any user can place files in the folder. If user jldera
saves a document in the /Users/Shared
folder, he can set its permissions to allow others on the system to access the file. However, those users would not have the permissions necessary to delete the file. Only jldera
(or an administrator) would be able to remove the file from the /Users/Shared
folder.
Another unique way that Unix uses permissions is through the use of Set UID
and Set GID
. When you execute an application, it runs as your user and is granted the same permissions to the filesystem as you have. Set UID and Set GID allow you to change this behavior so that a file is always executed as its owner and not necessarily the user who issues the command. While it might not be immediately apparent how this could help you on a day-to-day basis, the need becomes apparent when you look at system commands, such as sudo
.
As an administrative user, you use the sudo
command for temporarily gaining superuser privileges. This is often necessary when working with files that are integral to Mac OS X. The dialog box that prompts you for your password when installing software is the graphical equivalent of this practice. To do its job, the sudo
command needs to be able to run as the superuser. After all, it can’t grant you more power than it possesses. This is the directory listing for sudo
:
-r-s—x--x 1 root wheel 104428 Mar 20 19:03 /usr/bin/sudo
The file is executable by anyone. However, no matter who executes the command, it runs as root
and with root
’s privileges. This is a powerful tool, but it should be used very cautiously. Notice that sudo
’s binary has only execute permissions for all users except root
. This is to prevent outsiders from even reading the file, let alone modifying it for some malicious purpose.
If you need to change the ownership of a file, directory, or even a directory tree, you can do so easily from the Finder by using the Inspector. Simply set the various pull-down menus to change the settings for Owner, Group, and Others. To accomplish some of the operations, you’ll need to click the padlock icon and authenticate yourself. An administrative user can change ownership for any other user’s files. On the command line, you’ll need to use the chown
and chmod
commands.
The chown
tool, short for “change ownership,” changes the owner of a file. Its basic syntax is:
chown owner file
where owner
is the username or user ID of the new owner for the specified file
. For example, to change the owner of the file ImportantDocument.doc to alisa, you would use the following command:
$ sudo chown alisa ImportantDocument.doc
You have to issue this command with sudo
, because you need to authenticate yourself as an administrator to make this change. After all, you may not want a user to put files under the ownership of somebody else without oversight.
You can also change both the user and group settings for a file by using the following syntax:
chown owner:group file
where the owner
and group
arguments are separated by a colon. For example, to give everyone in the group sales access to the document, you would use the following command:
$ sudo chown alisa:sales ImportantDocument.doc
If you would like to change only the group owner of a file, you can leave the owner
argument blank. You still must include the separating colon, however, to prevent chown
from assuming you want to change the file’s user owner:
chown :group file
The chmod
tool, short for “change file modes,” changes the permissions on a file. Its basic syntax is:
chmod access-string file
where the access-string
states the permissions you want to set for the given file
. The access string has three parts to it: a letter (u
, g
, o
, a
), an operation code (+
, -
, =
), and a permission (r
, w
, x
). Table 8-4 gives a summary of what these codes represent.
Table 8-4. Commonly used chmod code summary
String part |
Code |
Description |
---|---|---|
Who |
|
User |
|
Group | |
|
Other | |
|
All (default) | |
Operation |
|
Add permission |
|
Remove permission | |
|
Assign only this permission, removing others | |
Permission |
|
Read |
|
Write | |
|
Execute (file) or search (directory) | |
|
Sticky bit |
For example, to give everybody write access for a file that you own:
$ chmod a+w ImportantDocument.doc
To enable execution of a file for everyone in the group that owns the file:
$ chmod g+x generatereport
To remove the ability to execute a file from all users:
$ chmod -x generatereport
To remove the ability to read a file from everyone but yourself:
$ chmod go-r ImportantDocument.doc
Or, if you need to set the sticky bit:
$ chmod u+t /Common
You can recursively change the permissions of a group of files by using the -R option. For example, if you wanted to allow everybody to see all the documents in your Documents folder, you would use the following command:
$ chmod -R +r Documents
You can also use commas to set more than one permission at a time. For example:
$ chmod a-wx,a+r ImportantDocument.doc
Alternatively, you can specify the mode of a file in another format; however, this is a more arcane syntax. To understand this syntax, you have to think in terms of bits and octal notation. A typical mode in this syntax contains three digits—each corresponding to the three levels of permission (user, group, other). Each digit is calculated by adding the octal values shown in Table 8-5.
Table 8-5. Octal values for assigning file permissions
Octal value |
Function |
---|---|
4 |
Read |
2 |
Write |
1 |
Execute |
0 |
No permission |
Some common number combinations for setting permissions are shown in Table 8-6. For example, if you wanted to grant read and write permissions for a user and only read permissions for group and others:
$ chmod 644 ImportantDocument.doc
Here, 644 indicates that the user who created the file has read-write privileges (4 + 2 = 6), and the group and others only get read-only access, as indicated by the 4s.
To grant all permissions to the user and deny all permissions to the group and others:
$ chmod 700 ImportantDocument.doc
Table 8-6. Commonly used chmod numeric sequences
Number |
Result |
Description |
---|---|---|
777 |
|
File can be read, written, or executed by anyone. |
774 |
|
File can be read and executed by anyone, but written to only by owner or group. |
755 |
|
File can be read and executed by anyone, but written to only by owner. |
666 |
|
File can be read and written by anyone, but can’t be executed. |
664 |
|
File can be read by anyone, written by owner or group, and can’t be executed. |
644 |
|
File can be read by anyone, written by owner, and can’t be executed. |
444 |
|
File is read-only. |
Although the Unix permission model works well in most cases, there are times when it doesn’t quite cover all your needs. For example, it isn’t possible to grant two members of the same group different types of access to the same file. If you allow one group member to write to the file, all of them can. Similarly, you can’t grant a third user access to that one file without making her a part of the group and giving her access to all of the rest of the group’s files.
These and similar limitations have plagued the Unix community for years, forcing many Unixes to release their own implementations of Access Control Lists
(ACLs). Apple has followed suit with the release of Tiger, bringing ACLs to Mac OS X. While they aren’t something you’ll likely use much on a single Mac, ACLs are a huge feature in network environments. Mac OS X Tiger Server adds ACL support right in the GUI, making it easy and intuitive to manage Access Control Entries
(ACEs).
The client version of Mac OS X isn’t so lucky, however. If you find you’ve reached the limits of the Unix permissions model, you’ll have to delve into the command line to work with the ACLs on your system. The two commands you’ll use most when working with ACLs should be familiar to you by now. The chmod
command is used to set up your ACLs, and ls
will help you view them. But, before delving into how to change your files’ ACLs, the next section tells you what you can change.
By default, ACLs are not enabled on the client version of Mac OS X. You can use the command sudo /usr/sbin/fsaclctl -p / -e
to enable them on the boot volume (/
).
Access Control Lists are made up of a series of Access Control Entries (ACEs). ACEs are simple rules that specify the user or group involved, whether access is denied or granted, and the type of access in question. When a user requests access to a file, Mac OS X consults each ACE within the ACL, in order, and uses the first matching rule. If it reaches the end of the ACL without a match, Mac OS X resorts to using the Unix permissions system to determine access privileges. Table 8-7 lists some of the more basic permissions that can be controlled using ACLs. You can find a more detailed list on the chmod
manpage or in Workgroup Manager on Tiger Server.
As mentioned earlier, the two commands you’ll use most frequently when working with ACLs are chmod
and ls
. Each has been given an extra switch or two for viewing and manipulating a file’s ACEs. In the case of ls
, the -e
switch has been added to provide a way to look at a file’s ACL. In Example 8-9, the file AnotherDoc.doc
has a single ACE that allows the user panic
to read the file, despite the fact that the file’s Unix permissions would prevent it. If a user besides panic
(or jldera
, of course) attempted to read the file, he would be denied access.
Example 8-9. Viewing a file’s Access Control Entries
$ ls -le
total 121648
-rw------- + 1 jldera jldera 18931712 Jun 15 14:43 AnotherDoc.doc
0: user:panic allow read
-rw-r—r-- 1 jldera jldera 43352064 Jun 15 14:43 SomeDoc.doc
ACLs are far more flexible than traditional Unix permissions. They offer much finer-grained control over who can do what with a file or folder. Much like traditional Unix permissions, you use the chmod
command to manipulate a file’s ACEs from the command line. Tiger’s chmod
has two new switches: +a
and -a
. They are used for adding and removing ACEs, respectively. To add an ACE to a file, use the syntax:
chmod +a "user
access
permission
"file
where user
is the user (or group) to whom the entry applies, access
is either allow
or deny
, and permission
is the type of access you want to restrict or grant. For example, to grant the user alisa
read access to the file AnotherDoc.doc
, you would use the command:
$ chmod +a "alisa allow read" AnotherDoc.doc
Here’s is the directory listing for AnotherDoc.doc
after adding the new Access Control Entry.
$ ls -le AnotherDoc.doc
-rw------- + 1 jldera jldera 18931712 Jun 15 14:43 AnotherDoc.doc
0: user:alisa allow read
1: user:panic allow read
Removing an ACE is very similar to adding an entry. Note that you should not add a rule that counteracts your undesired rule (that is, a deny
rule to override an allow
rule). Instead, remove the unwanted rule using the syntax:
chmod -a "user access permission
"file
Not only has Mac OS X’s complex parentage brought a variety of applications and tools, but it has also brought us multiple types of file attributes. Beyond the simple Unix owners, permissions, and ACLs, there are BSD file flags and HFS+ attributes. Both of these methods allow further refinement of access to files, and both also bring their own commands and options.
There are quite a few different BSD file flags available, but only a handful see frequent use. These can be further broken down into two types: system and user. System flags can be set only by the superuser and may be removed only when the system is in single-user mode (see Chapter 5 for more information on single-user mode). User flags can be set and unset at any time by any user with adequate permissions to access the file being manipulated. Table 8-8 contains a list of the most common file flags.
Table 8-8. Commonly used BSD file flags
Class |
Flag |
Description |
---|---|---|
System |
|
Makes the file append-only |
|
Makes the file unmodifiable | |
User |
|
Makes the file append-only |
|
Makes the file unmodifiable |
While it is not possible to view a file’s flags using the Finder, it’s a snap in the Terminal. To view the flags, use the ls
command’s -lo
options, as shown in Example 8-10.
Example 8-10. A directory listing showing BSD file flags
$ ls -lo
total 0
-rw-r—r-- 1 jldera jldera uappnd 0 Apr 22 11:45 appendonly
-rw-r—r-- 1 jldera jldera uchg 0 Apr 22 11:52 cantchangeme
The chflags
(change flags) tool is used for modifying BSD file flags. Its syntax is:
chflags flag file
where flag
is one of the BSD file flags noted in Table 8-8. If you would like to remove a file flag, preface its name with no
. For example, to remove the uchg
flag from the cantchangeme
file listed in Example 8-10, use this command:
$ chflags nouchg cantchangeme
Though UFS is available for use with Mac OS X, most Macs will have their hard drives formatted in HFS+. HFS+ brings its own features and idiosyncrasies (covered in detail in Chapter 9), but the one most relevant to file access is the HFS+ attribute set. These attributes , like BSD file flags, work in concert with the standard file permissions model to provide additional flexibility in controlling who may view, modify, or otherwise work with your data.
The two HFS+ attributes
that are most useful when restricting file access are the Invisible and Locked attributes. While the Locked attribute is quite similar to the uchg
file flag noted earlier, the Invisible flag can be a bit misleading. Files marked with the HFS+ Invisible attribute are not displayed in the Finder; however, they are still plainly visible in the shell.
Table 8-9 contains some common HFS+ attributes. When an attribute’s letter is lowercase, that attribute does not apply; when uppercase, the attribute is in effect.
Table 8-9. Commonly used HFS+ attributes
Attribute |
Description |
---|---|
A |
The file is an alias. |
C |
The file or folder has a custom icon. |
E |
The file’s or folder’s extension is hidden. |
L |
The file is locked. |
V |
The file or folder is invisible. |
There are two command-line tools available for working with HFS+ file attributes. Though the tools are not a part of the default Mac OS X install, you can easily acquire them by installing the Xcode Tools. With Xcode installed, you can find the pertinent commands in /Developer/Tools
. Remember that if you haven’t added the directory /Developer/Tools
to your shell’s command path (as discussed in Chapter 4), you must specify a complete path when working with these commands.
To view a file’s HFS+ attributes, you’ll want to make use of the GetFileInfo
command. The syntax is pretty straightforward, but reading the output can be tricky. Example 8-11 shows sample output from GetFileInfo
. The fourth line of the command’s output lists all of the file’s possible attributes, capitalizing those that are in effect. In the case of Financial.xls
, the file’s extension is hidden (capital “E”) and it is locked to prevent modification (capital “L”).
Example 8-11. Sample output from the GetFileInfo command
$ /Developer/Tools/GetFileInfo Financial.xls
file: "/Users/jldera/Documents/Financial.xls"
type: "XLS8"
creator: "XCEL"
attributes: avbstcLinmEdz
created: 08/25/2004 11:35:49
modified: 01/27/2005 10:36:23
GetFileInfo
’s counterpart is SetFile
. You’ll find it in the same folder as GetFileInfo
, and the two share a similar syntax. The
SetFile
command is used for changing a file’s attributes. If locking Financial.xls
from changes was not enough to protect it, you can make the file hidden using this command:
$ /Developer/Tools/SetFile -a V Financial.xls
As mentioned earlier, you’ll want to capitalize the letter of any attribute you wish to apply; using a lowercase letter removes the attribute. GetFileInfo
and SetFile
also give you access to even more forms of file metadata. These extra bits of file information are used by Mac OS X in some unique ways that are covered in the "Type and Creator Codes" section, later in this chapter.