Mac OS X supports two methods of controlling who can access a file and how they can access it: traditional UNIX access permissions (called permissions) and Access Control Lists (ACLs, page 97). ACLs provide finer-grained control of access privileges. You can also set file flags to limit a file's use. This section describes access permissions and file flags.
Three types of users can access a file: the owner of the file (owner), a member of a group to which the owner belongs (group), and everyone else (other). A user can attempt to access an ordinary file in three ways: by trying to read from, write to, or execute it. Three types of users, each of whom is able to access a file in three ways, equals a total of nine possible ways to access an ordinary file.
ls -l: Displays Permissions
When you call ls with the l option and the name of an ordinary file, ls displays a line of information about the file. The following example displays information for two files. The file letter.0610 contains the text of a letter, and check_spell contains a shell script, a program written in a high-level shell programming language:
$ ls -l letter.0610 check_spell -rw-r--r-- 1 zach zach 3355 May 2 10:52 letter.0610 -rwxr-xr-x 2 zach zach 852 May 5 14:03 check_spell
From left to right, the lines that an ls l command displays contain the following information (refer to Figure 4-11):
Figure 4-11. The columns displayed by an ls l command
The type of file (first column) for letter.0610 is a hyphen (-) because it is an ordinary file (directory files have a d in this column).
The next three characters specify the access permissions for the owner of the file: r indicates read permission and w indicates write permission. The in the next column indicates that the owner does not have execute permission; otherwise, an x would appear here.
In a similar manner the next three characters represent permissions for the group, and the final three characters represent permissions for other (everyone else). In the preceding example, the owner of letter.0610 can read from and write to the file, whereas the group and others can only read from the file and no one is allowed to execute it. Although execute permission can be allowed for any file, it does not make sense to assign execute permission to a file that contains a document, such as a letter. The check_spell file is an executable shell script, and execute permission is appropriate. (The owner, group, and others have execute access permission.)
An lsl command displays a plus sign (+) between the permissions and the number of links for files that have an ACL (page 97), even if the list is empty.
chmod: Changes Access Permissions
The owner of a file controls which users have permission to access the file and how they can access it. When you own a file, you can use the chmod (change mode) utility to change access permissions for that file. In the following example, chmod adds (+) read and write permissions (rw) for all (a) users:
$ chmod a+rw letter.0610 $ ls -l letter.0610 -rw-rw-rw- 1 zach zach 3355 May 2 10:52 letter.0610
Tip: You must have read permission to execute a shell script
Because a shell needs to read a shell script (a text file containing shell commands) before it can execute the commands within the script, you must have read permission for the file containing the script to execute it. You also need execute permission to execute a shell script directly on the command line. Binary (program) files do not need to be read; they are executed directly. You need only execute permission to run a binary (nonshell) program.
In the next example, chmod removes (-) read and execute (rx) permissions for users other (o) than the owner of the file (Zach) and members of the group associated with the file (zach):
$ chmod o-rx check_spell $ ls -l check_spell -rwxr-x--- 2 zach zach 852 May 5 14:03 check_spell
In addition to a (all) and o (other), you can use g (group) and u (user, although user refers to the owner of the file who may or may not be the user of the file at any given time) in the argument to chmod. Refer to page 265 for more information on using chmod to make a file executable.
Tip: chmod: o for other, u for owner
When using chmod, many people assume that the o stands for owner; it does not. The o stands for other, whereas u stands for owner (user).
The Mac OS X file access permission scheme lets you give other users access to the files you want to share yet keep your private files confidential. You can allow other users to read from and write to a file (you may be one of several people working on a joint project). You can allow others only to read from a file (perhaps a project specification you are proposing). Or you can allow others only to write to a file (similar to an inbox or mailbox, where you want others to be able to send you mail but do not want them to read your mail). Similarly you can protect entire directories from being scanned (covered shortly).
There is an exception to the access permissions just described. Anyone who knows the root password or is in the admin group can log in as Superuser (page 427) or use sudo (page 431) and gain full access to all files, regardless of owner or access permissions.
Groups (page 934) allow users to share files or programs without allowing all system users access to them. This scheme is useful if several users are working with files that are not public. In a traditional UNIX system, the /etc/group file associates one or more usernames with each group (number). Under OS X this file is used in single-user mode only. When OS X is in multiuser mode it relies on NetInfo (page 441) to provide group information.
Each user has a primary group, the group that user is assigned in the passwd database. By default Mac OS X has user private groups: Each user's primary group has the same name as the user's username. For example, the user with the username max is a member of the group named max. In addition, a user can belong to other groups. In effect, you simultaneously belong to both your primary group and any groups you are assigned to. When you attempt to access a file that you do not own, the operating system checks whether you are a member of the group that has access to the file. If you are, your access permissions are controlled by the group access permissions for the file. If you are not a member of the group that has access to the file and you do not own the file, you are subject to the public (other) access permissions for the file.
When you create a new file, it is assigned to the group associated with the directory the file is being written into, even if you do not belong to that group. You can change the group that a file is associated with by using the chgrp command (page 675), but you can change it only to a group of which you are a member (unless you are working as root). You can see which groups a user is in by using the groups utility:
$ groups zach zach admin
Setuid and Setgid Permissions
When you execute a file that has setuid (set user ID) permission, the process executing the file takes on the privileges of the file's owner. For example, if you run a setuid program that removes all files in a directory, you can remove files in any of the file owner's directories, even if you do not normally have permission to do so.
In a similar manner, setgid (set group ID) permission means that the process executing the file takes on the privileges of the group the file is associated with. The ls utility shows setuid permission by placing an s in the owner's executable position and setgid permission by placing an s in the group's executable position:
$ ls -l program1 -rwxr-xr-x 1 zach zach 15828 Nov 5 06:28 program1 $ chmod u+s program1 $ ls -l program1 -rwsr-xr-x 1 zach zach 15828 Nov 5 06:28 program1 $ chmod g+s program1 $ ls -l program1 -rwsr-sr-x 1 zach zach 15828 Nov 5 06:28 program1
Directory Access Permissions
Access permissions have slightly different meanings when they are used with directories. Although the three types of users can read from or write to a directory, the directory cannot be executed. Execute access permission is redefined for a directory: It means that you can cd into the directory and/or examine files that you have permission to read from in the directory. It has nothing to do with executing a file.
Security: Minimize use of setuid and setgid programs owned by root
Executable files that are setuid and owned by root have Superuser privileges when they are run, even if they are not run by root. This type of program is very powerful because it can do anything that Superuser can do (that the program is designed to do). Similarly executable files that are setgid and belong to the group root have extensive privileges.
Because of the power they hold and their potential for destruction, avoid creating indiscriminately and using setuid and setgid programs owned by or belonging to the group root. Because of their inherent dangers, many sites do not allow these programs on their systems. See page 429 for information on setuid files owned by root.
Security: Do not write setuid shell scripts
Never give shell scripts setuid permission. Several techniques for subverting them are well known.
When you have only execute permission for a directory, you can use ls to list a file in the directory if you know its name. You cannot use ls without an argument to list the entire contents of the directory. In the following exchange, Max first verifies that he is logged in as himself. Then he checks the permissions on Zach's info directory. You can view the access permissions associated with a directory by running ls with the d (directory) and l (long) options:
$ who am i max ttyp1 Jul 31 22:16 (bravo.example.co) $ ls -ld /Users/zach/info drwx-----x 4 zach zach 136 Aug 1 12:00 /Users/zach/info $ ls -l /Users/zach/info ls: info: Permission denied
The d at the left end of the line that ls displays indicates that /Users/zach/info is a directory. Zach has read, write, and execute permissions; members of the zach group have no access permissions; and other users have execute permission only, as indicated by the x at the right end of the permissions. Because Max does not have read permission for the directory, the ls l command returns an error.
When Max specifies the names of the files he wants information about, he is not reading new directory information but rather searching for specific information, which he is allowed to do with execute access to the directory. He has read access to notes so he has no problem using cat to display the file. He cannot display financial because he does not have read access to it:
$ ls -l /Users/zach/info/financial /Users/zach/info/notes -rw------- 1 zach zach 39 Aug 1 12:00 /Users/zach/info/financial -rw-r--r-- 1 zach zach 30 Aug 1 12:00 /Users/zach/info/notes $ cat /Users/zach/info/financial cat: /Users/zach/info/financial: Permission denied $ cat /Users/zach/info/notes This is the file named notes.
Next Zach gives others read access to his info directory:
$ chmod o+r /Users/zach/info
When Max checks his access permissions on info, he finds that he has both read and execute access to the directory. Now ls l works without arguments, but he still cannot read financial. (This is an issue of file permissions, not directory permissions.) Finally Max tries to create a file named newfile by using touch (page 877). If Zach were to give him write permission to the info directory, Max would be able to create new files in it:
$ ls -ld /Users/zach/info drwx---r-x 4 zach zach 136 Aug 1 12:00 /Users/zach/info $ ls -l /Users/zach/info total 16 -rw------- 1 zach zach 39 Aug 1 12:00 financial -rw-r--r-- 1 zach zach 30 Aug 1 12:00 notes $ cat /Users/zach/info/financial cat: /Users/zach/info/financial: Permission denied $ touch /Users/zach/info/newfile touch: /Users/zach/info/newfile: Permission denied
In addition to traditional UNIX permissions and ACLs, Mac OS X supports BSD file flags. File flags primarily limit a file's use. An ls lo command displays file flags between the group and size fields. The memo.txt file has the nodump and uchg file flags set:
$ ls -lo memo.txt -rw-r--r-- 1 sam sam uchg,nodump 82556 Aug 1 12:45 memo.txt
The uchg file flag prevents anyone from changing or removing a file, and nodump prevents a file from being dumped. The following example shows the contents of the sample file and shows that it has no file flags set (the hyphen in the file flags position indicates that no file flags are set):
$ cat sample This is a sample file. $ ls -lo sample -rw-r--r-- 1 sam sam - 23 Aug 1 12:35 sample
Tip: The uchg flag is the same as the locked attribute
Although BSD flags and attribute flags (page 95) are not generally the same, the uchg flag and the locked attribute are interchangeable. Setting one sets the other and clearing one clears the other.
Next chflags sets the uchg file flag on sample. Once the uchg file flag is set, no one can modify or remove the file. This file flag overrides the traditional UNIX permissions that would normally allow you to remove a file from a directory that you own:
$ chflags uchg sample $ ls -lo sample -rw-r--r-- 1 sam sam uchg 23 Aug 1 12:35 sample $ cp memo.txt sample cp: sample: Operation not permitted $ rm sample override rw-r--r-- sam/sam uchg for sample? y rm: sample: Operation not permitted
You clear a flag the same way that you set it, except you precede the name of the flag with the string no:
$ chflags nouchg sample $ rm sample $
File flags cannot be overridden by anyone, not even root. The uchg file flag is a user file flag. It can be set and cleared by the owner of a file or root. The schg file flag is a system file flag that protects a file the way the uchg user file flag does. System file flags can be set only by root and can be cleared by root only in single-user mode. For more information on file flags, see the chflags man page.