From left to right, the lines that an
ls l
command displays contain the following information (refer to Figure 4-11):
-
The type of file (first character)
-
The file's access permissions (the
next
nine
characters
)
-
The ACL flag (present if the file has an ACL)
-
The number of links to the file (see page 102)
-
The name of the owner of the file (usually the person who created the file)
-
The name of the group that has group access to the file
-
The
size
of the file in characters (bytes)
-
The date and time the file was created or last modified
-
The name of the file
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
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
File Flags
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.
chflags
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.