Ninety percent of day-to-day problems in running Unix systems are permissions- related . Most often, some process tries to write to a file or directory that it doesn't have permission to write to. Maybe it did yesterday , but someone accidentally or carelessly changed it, and then something stopped working.
Permission problems show up in so many ways that it is not reasonable to try to list them here, but there are a few rules you can follow to spot permission problems.
Often the first sign is an error message containing the words "Permission denied ." Sometimes it is accompanied by more informationfor example,
/usr/local/bin/script.sh: permission denied: /etc/foo [3]
This is telling you that line 3 of the script /usr/local/bin/script.sh failed because it did not have enough permission to do something with /etc/foo . You have to look inside the script to see what exactly was going on, but you have a good place to start.
Some things to keep in mind:
1. | To create a new file, rename a file, delete a file, or change a file's permissions, the process must have write permission in the directory where the file is being created. |
2. | To change an existing file, you must have write permission on the file. |
3. | To cd into a directory, the process must have execute permission on the full path of the directory. So to cd into /Users/ vanilla /Sites/images/big_images , the processes doing the cd must have execute permission on the following: / /Users /Users/vanilla /Users/vanilla/Sites /Users/vanilla/Sites /images /Users/vanilla/Sites /images/big_images |
4. | To list the contents of a subdirectory, you must have read permission for it, as well as permission to cd into the directory where it's stored. So to list the contents of /Users/vanilla/Sites/images/big_images , you must be able to cd into /Users/vanilla/Sites/images and have read permission on big_images. You do not need to be able to cd into a directory to list its contents. |
To correct a permission problem:
1. | Write down the permissions of the files or directories you think should change. You might try redirecting the output of ls -l into a file, for example: ls -l bad_file > permission_save |
2. | Change the permissions to what you think will fix the problem. |
3. | Test the fix. If the fix doesn't work, change the permissions back to what they started as, and think through the problem again. Go back to step 2. Lather, rinse, repeat. |
Starting with version 10.4 Mac OS X supports a form of permissions called an Access Control List (ACL). ACLs are special files, normally hidden from view, that allow you to specify in excruciating detail the kinds of access that users have to a file or directory. For example, using an ACL, you can give permission to append to a file but not to delete it, or to delete or create a file, but not to alter an existing file. And you can give these permissions separately to each user or group in the ACL.
ACLs are not enabled by default in the regular version of Mac OS X, but they are enabled in Mac OS X Server (see www.apple.com/server/documentation). There is also an article on understanding ACLs at www.afp548.com/article.php?story=20050506085817850. Or, check out Apple Training Series: Mac OS X Server Essentials, soon to be published by Peachpit Press, for much more about ACLs than we are able to cover here.
To enable ACLs:
1. | sudo fsaclctl -a -e Enter your password if asked for it. You will see a line of output for each filesystem (volume, partition) you have mounted, with at least the root filesystem being listed: ProcessVolume: processing / |
Tips
You can learn more about ACLs from the man page for the chmod and ls commands. These describe how to set and read ACLs. For example, to set an ACL you might do
chmod +a "admin allow write" filename
The folks at Ars Technica wrote an article that provides an excellent overview of the changes to Mac OS X that were introduced in version 10.4. The section on ACLs is http://arstechnica.com/reviews/os/macosx-10.4.ars/8.
To add an ACL entry:
chmod +a "dancers allow append" filename
K EYWORD | D ESCRIPTION |
---|---|
Permissions available for both files and directories : | |
delete | Deletes the object. You can delete an object if you have this permission or the delete_child permission on the immediate parent directory. |
readattr | Reads the object's basic attributes (filename, size , and so on) |
writeattr | Changes the normal Unix attributes of the object. |
readexattr | Reads the object's extended attributesthese are the attributes used in Spotlight searches. |
writeexattr | Alters the object's extended attributes. |
readsecurity | Reads the object's ACL. |
writesecurity | Writes an object's ACL. |
chown | Changes the object's ownership. |
Permissions available only for directories: | |
list | Lists the contents of the directory. |
search | Looks up files by name . |
add_file | Adds a file. |
add_subdirectory | Adds a subdirectory. |
delete_child | Deletes any object in the directory. (See also the delete permission, above.) |
file_inherit | Causes files (not directories) to inherit ACL settings. |
directory_inherit | Causes subdirectories (not files) to inherit ACL settings. |
limit_inherit | Causes an inherited ACL entry to not be inherited any further down the hierarchyit stops here, so this one only applies to inherited entries. |
only_inherit | The entry is inherited but has no effect. |
Permissions available only for non-directories: | |
read | Like the standard Unix read permissionallows reading the file contents. |
write | Allows writing to the file. |
append | Like write , but only allows writes into areas in the file that have not already been written. |
execute | Like the standard Unix execute permission for a file. |
O PTION | D ESCRIPTION |
---|---|
+a | Set (add) an ACL entry. |
+a# n | Add an entry at position n ( lowest number is 0) |
-a | Remove an entry. |
-a# n | Remove entry at position n (lowest position is 0) |
=a# n | Rewrite an existing entry at position n . |
-E | Read the ACL entries (separated by newlines) from STDIN, so you can redirect input from a file with chmod -E < acl_entries_file |
-i | Removes the "inherited" setting from all entries in the named file(s)' ACLs. See the man page for chmod for more on complex inheritance possibilities of ACL entries. |
-I | Removes all inherited entries from the named file(s)' ACLs. |
Adding an ACL entry to allow group "dancers" to write to a file: root# ls -le total 8 -rw-r--r-- 1 vanilla wheel 13 Jul 11 20:18 file1 root# chmod +a "dancers allow write" file1 root# ls -le total 8 -rw-r--r-- + 1 vanilla wheel 13 Jul 11 20:18 file1 0: group:dancers allow write Adding an ACL entry on a directory to allow group dancers to add files to the directory: root# ls -le total 0 drwxr-xr-x 2 root wheel 68 Jul 11 20:23 dropbox root# chmod +a "dancers allow add_file" dropbox root# ls -le total 0 drwxr-xr-x + 2 root wheel 68 Jul 11 20:23 dropbox 0: group:dancers allow add_file (Notice how the second use of ls -le, after adding an ACL entry, added a + to the output of ls .) Adding an ACL entry giving user "vanilla" three permissions (add_file, list, and search) on the directory: root# chmod +a "vanilla allow add_file,list,search" dropbox root# ls -le total 0 drwxr-xr-x + 2 root wheel 68 Jul 11 20:29 dropbox 0: user:vanilla allow list,add_file,search 1: group:dancers allow add_file Removing an ACL entry by position number: root# ls -le total 0 drwxr-xr-x + 2 root wheel 68 Jul 11 20:29 dropbox 0: user:vanilla allow list,add_file,search 1: group:dancers allow add_file root# chmod -a# 1 dropbox root# ls -le total 0 drwxr-xr-x + 2 root wheel 68 Jul 11 20:29 dropbox 0: user:vanilla allow list,add_file,search
Tips
ACL entries normally get added to the "top" of the ACL list (in position 1 as shown by the ls -le command), but you can specify a position for a new ACL entry by using the +a# optionfor example:
chmod +a# 3 "probies deny write" inbox
would put the new ACL entry at position 3. If there was already an entry at position 3, it would now be at position 4.
ACLs support specifying (for directories only) how ACL settings are passed down to files and directories contained inside the directory. This is called inheritance . See the man page for chmod for details.
To remove an ACL entry:
chmod -a "probies deny write" filename
To alter an existing ACL entry:
chmod =a# 2 "dancers allow read" filename