|< Day Day Up >|
Introduction to File Permissions
This section expands on the topic of file permissions, which were briefly mentioned when we discussed the output from the ls command. It's likely that you won't have an immediate use for modifying file permissions, and it's possible that you'll never need to deal with them at all. However, if you want to work with other users on the same system, or decide to start writing your own programs, understanding the permission system will be necessary.
Read, Write, and Execute
Permissions are specified as a collection of three flags. These flags (also called bits) control whether data in the file may be read, written, and executed. Unix takes these flags literally. So, if you have a program and you unset its execute flag, you won't be able to run the program the system simply won't understand that the program is executable. Likewise, if you set the execute flag for a file containing a word processor document, Unix will assume that the file contents are a program and try its best to run the file. This is unlikely to do anything but produce an error message.
In the case of directories, the same bits apply, but the meanings are slightly different. The read and write bits control whether the contents of the directory may be read, and whether the directory can be written to, respectively. The execute bit, however, controls whether the directory can be cded to, or otherwise moved into by a shell or program.
The permissions for whether a directory listing can be read or written to are separate from the permission that controls whether you, or programs, can move into it. Also, the permissions for files contained in the directory do not necessarily need to agree with the permissions of the directory. The significance of this might not be immediately apparent, but the meaning is literal. If you have files that have world read permission turned on, you can put them in a directory and set the bits on the directory so that the files in it can be read, but the files can't be listed. Likewise, you can set the permissions so that the directory allows anyone on the system to write files into it, but nobody can read the files or list the contents.
The execute permission for directories interacts with the read and write permission for files in it, in a slightly nonintuitive fashion. Read permission for the directory allows you to read the directory listing but not the files. Read permission for a file in the directory allows you to read the file but not list the directory. However, to be able to read the file, you or rather the software you're using to read the file must be able to go into the directory. Because of this, if you turn on read permission for a directory and not execute permission, you can list the directory but not read the files, no matter what the permissions on the files are. Likewise, you (or software under your control) can't write into a directory with only write permission turned on; execute permission must be enabled as well.
If you know that the file fizbin exists in the directory thozbot, but read permission is turned off for thozbot and execute permission is turned on, you can still read fizbin (assuming that you have read permission on fizbin itself) by using its full or relative path from outside the thozbot directory. If you don't know that fizbin exists in the directory, there's no way for you to find out because you can't enter the directory or list the contents.
Owner, Group, and World
Adding a layer of complexity to the permission system, the read, write, and execute permissions detailed earlier can be specified separately for three subsets of users. They can be set for each owner of the file, the group owner of the file, and the world.
The owner of a file is, as the name implies, the user who owns the file. Each file on a Unix system has information stored about it that indicates to which user account the file belongs. Files that you create automatically belong to your user ID. Other files on the system belong to other users, or to one of the system accounts that exist to help the operating system keep its processes sorted out and secure.
Files have an additional piece of ownership information: the group ownership of the file. The group ownership specifies, by group name, a collection of users who share the group permissions to the file. This additional information facilitates the sharing of information among more than one user. Interestingly, the group permissions can be less than the permissions that are available to everybody, and when they are, the members of that group of users have restricted access to the file compared to other users of the machine, rather than enhanced access. Creating groups and controlling their membership are covered in Chapter 20, "Configuring Advanced System Features via NetInfo."
Finally, there is a set of permission bits that control the access level enjoyed by the world, or at least all the other users on the system. If you provide any sort of guest access to your machine, it's best to assume that the file's world permissions do in fact apply to just about everyone, independent of location.
In addition to the read, write, and execute bits for each file and directory, a few additional bits exist as well. These bits are typically used by system administrators, but they occasionally come in handy for other users.
The complete set of bits, including the extended bits, that control the permissions and properties of a file or directory are called the mode bits for the file.
Further extending the classical set of mode bits is a set of special flags. These are definitely not for use by anyone but the administrator, but are mentioned here because one particular bit can sneak up and bite you.
The most important of these for you to watch out for is the immutable flag. This flag is set by Finder's locked status for a file. It's not currently clear why Apple chose this particular flag to map to Finder's locked status, but it causes a few problems on the Unix side. Specifically, if you set a file's immutable flag, it becomes almost impossible to change that file in any way. It can't be modified, it can't be overwritten, it can't be deleted it becomes, as the name implies, immutable. Although Apple's tech notes indicate that there is a way to override the immutable flag and remove the file, this appears to only work for user-level immutable flags. If the system-level immutable flag (schg) becomes set, the only way we've found to remove it is to use ResEdit under Classic.
Checking File Permissions: ls -l
Remember that the ls -l command shows you the permissions associated with files. To find out the permissions associated with a single file, give it a filename to list:
brezup:ray testing $ ls -l /etc/passwd -rw-r--r-- 1 root wheel 1374 29 Jul 14:15 /etc/passwd
Controlling File Permissions: chmod
After you are comfortable examining the permissions of files, you'll probably want to be able to change them. This is accomplished with the chmod (change mode) command. This command operates in either a "fully specified mode bits" manner, or in a "change this specific mode bit" manner, depending on the arguments you give it on the command line.
The "change this specific mode bit" form is the friendlier of the two, and works by allowing you to specify a bit to change, how to change it, and which type of user to change it for. The complete syntax for this form of the command is
chmod <u|g|o|a><+|-><r|w|x> <filename> ...
To use it, simply do the following:
You might also use an a to indicate all, in place of the u, g, or o argument, if you want to make the change for the file to all three user types.
For example, consider a file named fizbin with the current permission set so that the user has full read, write, and execute permission, and the group and world have no permissions at all.
brezup:ray testing $ ls -l total 0 -rwx------ 1 ray staff 0 Apr 22 23:32 fizbin
Perhaps this file is not actually a program, and to prevent yourself from accidentally trying to run it, you want to remove the execute permission from the user.
brezup:ray testing $ chmod u-x fizbin brezup:ray testing $ ls -l total 0 -rw------- 1 ray staff 0 Apr 22 23:32 fizbin
Now you want to make it readable by both the group and the world.
brezup:ray testing $ chmod g+r fizbin brezup:ray testing $ chmod o+r fizbin brezup:ray testing $ ls -l total 0 -rw-r--r-- 1 ray staff 0 Apr 22 23:32 fizbin brezup:ray testing $ chmod u+x,g=rx,o=rx fizbin brezup:ray testing $ ls -l total 0 -rwxr-xr-x 1 ray staff 0 Apr 22 23:32 fizbin
As you can see, this method of changing file permissions is fairly simple, but it does not lend itself to setting many permissions at once. Although it's possible to say chmod u=rwx,g=xr,o=xr <filename> to set all the permission bits at once to force the file's mode bits into some particular pattern in a single command, doing so is a bit cumbersome. To solve this, the chmod command also includes an "all at once" option, whereby you can specify the full complement of mode bits simultaneously in a more compact form.
This form of the command can appear to be slightly less clear because it requires you to do a little math, but in reality it's no more complicated. In this form, the chmod command considers the mode bits for the file to be binary bits. To use the command, you need to specify which bits to set and which to unset.
Unfortunately, you can't do this in a manner as nice as just giving chmod a set of nine rwxrwxrwx characters or ones and zeros. Instead, you must break up the nine bits of the mode bit set into three sets of three bits (rwx rwx rwx), and calculate the decimal equivalent of the bits that you want set.
Put another way, you could think of the elements in rwx as specifying where, in a binary string, a 1 occurs. This is done as shown here:
100 - read permission. 100 in binary = 4 in decimal. 010 - write permission. 010 in binary = 2 in decimal. 001 - execute permission. 001 in binary = 1 in decimal.
To find the decimal value equivalent of a particular combination of r, w, and x bits, you sum the decimal values that correspond to the bit patterns that represent them. So, if you wanted read and execute permission, with no write permission, you would add 4 + 1 = 5, and for user, group, or world, you would put a 5 in the pattern where needed.
A full example should help to explain this. Let's again consider the fizbin file, which, due to the use of chmod previously, has mode bits of rw-r--r--. That is to say, the user can read and write, and both the group and world can read. If you wanted to change this to mode bits r-xr-x--x, the syntax shown for the friendlier mode of chmod would require several commands. Instead, you could make this change in a single command by using the "all at once" form. To do so, follow these steps:
Let's see whether it works:
brezup:ray testing $ ls -l total 0 -rw-r--r-- 1 ray staff 0 Apr 22 23:32 fizbin brezup:ray testing $ chmod 551 fizbin brezup:ray testing $ ls -l total 0 -r-xr-x--x 1 ray staff 0 Apr 22 23:32 fizbin
Table 11.1 shows the command syntax and the most interesting options for chmod. The complete documentation is available in the online appendix.
Controlling a File's Permissions Using the Finder
You also have limited access to the permission flags from Finder's Get Info window for a file or directory. Choose the Ownership & Permissions pane of the Get Info window after selecting the file or folder you want to adjust. Your display should look similar to Figure 11.1.
Figure 11.1. The Permissions section of the Get Info window allows you to specify what you can do what with a file.
The Finder makes it easy to adjust permissions without getting into nitty-gritty details such as file ownership. By default, the pop-up menu labeled You Can allows you to choose what you want to be able to do with a file. Choose from the following:
If this doesn't suit your fancy, you can gain finer-grained control by expanding the Details section of the Ownership & Permissions pane, as shown in Figure 11.2.
Figure 11.2. The Details section of the Get Info window allows you finer-grained control over the permissions.
Here, there are three levels of access you can adjust:
For each of these levels of access, there are multiple user rights. Adjusting these rights controls what the owner, group, and everyone else can do to a file or folder. These don't give quite the range of options available through chmod, but are good for many common uses. When viewing the file information for a folder, the window also shows an Apply to Enclosed Items button that copies all the access rights on the folder to the files underneath. If a folder has read permission turned off, the files inside the folder may still be accessed or modified unless they too have read permission removed.
A final setting exists for nonboot (storage) volumes. If a disk is selected while viewing permission information, an Ignore Ownership on This Volume check box appears. Clicking this box causes the volume to appear as open and unrestricted to the operating system, regardless of what permissions might have previously been applied to a system. Users of your system can modify anything on the drive. Activating this setting is not recommended, but it's sometimes necessary, especially when porting data over from a machine with different users. Keep this in mind when thinking about your files and security just because you've set your permissions to deny access to other users, are they really secure? Not if potentially nosy users can get their hands on your drive, and attach it to their own system. Your system-level security settings are only as good as your physical security for the device.
Controlling a File's Ownership
Sometimes it's necessary (or useful) to change the users who have control or access to a file. This can be accomplished by changing the file's individual owner or changing the group to which the file belongs. Only root can change a file's ownership, but the owner a file can change its group to any valid group in which she is a member.
Controlling a File's Primary Ownership: chown
Changing the ownership of a file (possible only for the root user) is accomplished using the chown command. The usage is chown <newowner>[:<newgroup>] file. That is, if root wants to change the ownership of a file named test1 so that it is now owned by joray, it might be done like this:
brezup:root testing # ls -l total 0 -rw-r--r-- 1 ray ray 0 Jan 3 20:34 test1 -rw-r--r-- 1 ray ray 0 Jan 3 20:34 test2 brezup:root testing # chown joray test1 brezup:root testing # ls -l total 0 -rw-r--r-- 1 joray ray 0 Jan 3 20:34 test1 -rw-r--r-- 1 ray ray 0 Jan 3 20:34 test2
If root would also like to change test2, and simultaneously change the group associated with the file to the staff group, this could be done like this:
brezup:root testing # chown joray:staff test2 brezup:root testing # ls -l total 0 -rw-r--r-- 1 joray ray 0 Jan 3 20:34 test1 -rw-r--r-- 1 joray staff 0 Jan 3 20:34 test2
chown also takes several optional command-line flags that control its behavior similarly to the chmod flags. That is, optionally causing it to recursively descend directory trees, and controlling its behavior with respect to symbolic links. The command documentation table for chown is shown in Table 11.2.
Controlling a File's Group Ownership: chgrp
As mentioned in Chapter 8, a user may belong to multiple different groups. How these groups are created and managed will be covered in Chapter 20. Each of the groups that are configured on a system, and that a user might belong to, may have different purposes on the system; for example, allowing groups of individual users to collaborate on projects, and allowing some users to belong to multiple different project groups.
By default in Tiger, a new group is created for each individual user, and each normal user belongs only to that group. This is in contrast to more traditional Unix systems where there are "class of user" type groups, such as Users, Staff, and Guests, and typical users are all members of a common group (in addition to any other groups they may belong to), allowing their permissions to be managed collectively. The "each user gets a group" philosophy seems to have been dragged in by the recent Linux explosion, where this idea was made popular. It is not a favorite of administrators who like to keep their machines organized and manageable, but it does provide significant flexibility if you have users who each want to have an individualized list of buddies with specialized access to their files.
A user who is a member of a group can access files that have that same group as their group owner. Unlike with some real-life groups of people, each user can simultaneously participate in all groups of which they are a member, no matter how many groups that might be. This makes perfect sense for accessing files you can access a file that belongs to any group of which you are a member at any time.
Creating new files is a little more confusing. A file has only one group ownership, so there has to be some way of determining which of the many groups you belong to the new file gets created as belonging to. In current BSD-derived versions of Unix, this determination is based on the group ownership of the directory you're in. Whatever group owns the directory you're working in, this is the group to which any files you create in the directory will have their group ownership set. This is true regardless of whether you are actually a member of this group.
In addition to being created as belonging to the group owner of the current directory, group ownership of a file can be further controlled by the file's owner. The owner of a file has the ability to change the group ownership of a file to any group to which the owner belongs. Issuing chgrp <groupname> <filename> switches the group ownership of <filename> to <groupname>, assuming that you are a member of <groupname>. Table 11.3 shows the command syntax and most interesting options for chgrp. The complete documentation is shown in the online Appendix.
Controlling the Special Flags: chflags
To modify the special flags, you use the chflags command. It's not at all clear what Apple is using the special flags for at the moment, although we do know that the Finder's locked status of a file sets the immutable bit on the Unix side. To make matters even more confusing than the lack of documentation makes things, the behavior in Tiger is (at least with the developer preview) different than the behavior under earlier versions of Mac OS X. In Tiger, it appears that the system-immutable flag (the immutable flag as set by root) is either disabled or broken. In a sense, this is a good thing. Under earlier versions of Mac OS X (and possibly under Tiger as well, if this turns out to be a bug, rather than a feature), the system immutable flag could create a file that was not changeable by anyone, ever. For example, using Panther
brezup:ray testing 141$ ls -l total 0 -rw-r--r-- 1 ray staff - 0 Jun 27 14:22 test -rw-r--r-- 1 ray staff - 0 Jun 27 14:22 test2 brezup:ray testing 142$ su Password:
brezup:root testing 21# chflags schg test brezup:root testing 22# ls -ol total 0 -rw-r--r-- 1 ray staff schg 0 Jun 27 14:22 test -rw-r--r-- 1 ray staff - 0 Jun 27 14:22 test2 brezup:root testing 23# chflags noschg test chflags: test: Operation not permitted brezup:root testing 24# rm test override rw-r--r-- ray/staff for test? y rm: test: Operation not permitted brezup:root testing 25# exit brezup:ray testing 143$
The immutable flag is a relatively recent Unix invention and indicates that the file cannot be changed. It's clear from the example that immutable really means just that: Even root can't delete the file, and what's more, root can't even remove the system immutable flag after it has been set. If a user sets a user-immutable flag (uchg instead of schg), under previous version of Mac OS X the user can neither unset nor remove the flag, but root can remove the file using rm, whereas in Tiger, both the user and root can (correctly) use chflags nouchg to remove the user immutable flag.
Under Tiger (developer preview), the chflags schg command has no effect, even though it's documented as having one. On one hand, this prevents the file from landing in this limbo state where even root can't touch it again. On the other, it removes the ability to create truly immutable files. We don't know which is the larger problem. Even if Apple has removed the ability to set system-immutable flags for all future version of Mac OS X, the issue is still one that will have to be dealt with in any heterogeneous environment, or on any system where a previous version of Mac OS X has been installed.
When this bit is successfully set using Mac OS X 10.3 or earlier, even booting back into Mac OS 9.2 and trying to unlock the file from a Get Info dialog in Finder turns out to be insufficient. The only successful route that we've found thus far is to remove the locked flag by using the venerable ResEdit program!
We don't really recommend experimenting with the chflags command much because it has the potential to make a real mess of things, and there's no documentation of what Apple is using the rest of the flags for. We've included the syntax and more interesting options in Table 11.4, in case you should run across command examples using this in the future, as adventurous hackers pry the secrets out of Mac OS X.
|< Day Day Up >|