4.3. Permissions

FreeBSD, being a direct descendant of BSD UNIX®, is based on several key UNIX® concepts. The first and most pronounced is that FreeBSD is a multi-user operating system that can handle several users working simultaneously on completely unrelated tasks. The system is responsible for properly sharing and managing requests for hardware devices, peripherals, memory, and CPU time fairly to each user.

Much more information about user accounts is in the chapter about accounts. It is important to understand that each person (user) who uses the computer should be given their own username and password. The system keeps track of the people using the computer based on this username. Since it is often the case that several people are working on the same project UNIX® also provides groups. Several users can be placed in the same group.

Because the system is capable of supporting multiple users, everything the system manages has a set of permissions governing who can read, write, and execute the resource. These permissions are stored as three octets broken into three pieces, one for the owner of the file, one for the group that the file belongs to, and one for everyone else. This numerical representation works like this:

Note:

This section will discuss the traditional UNIX® permissions. For finer grained file system access control, see the File System Access Control Lists section.

ValuePermissionDirectory Listing
0No read, no write, no execute---
1No read, no write, execute--x
2No read, write, no execute-w-
3No read, write, execute-wx
4Read, no write, no executer--
5Read, no write, executer-x
6Read, write, no executerw-
7Read, write, executerwx

Use the -l argument to ls(1) to view a long directory listing that includes a column of information about a file's permissions for the owner, group, and everyone else. For example, a ls -l in an arbitrary directory may show:

% ls -l total 530 -rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile -rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile -rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt

The first (leftmost) character in the first column indicates whether this file is a regular file, a directory, a special character device, a socket, or any other special pseudo-file device. In this example, the - indicates a regular file. The next three characters, rw- in this example, give the permissions for the owner of the file. The next three characters, r--, give the permissions for the group that the file belongs to. The final three characters, r--, give the permissions for the rest of the world. A dash means that the permission is turned off. In this example, the permissions are set so the owner can read and write to the file, the group can read the file, and the rest of the world can only read the file. According to the table above, the permissions for this file would be 644, where each digit represents the three parts of the file's permission.

How does the system control permissions on devices? FreeBSD treats most hardware devices as a file that programs can open, read, and write data to. These special device files are stored in /dev/.

Directories are also treated as files. They have read, write, and execute permissions. The executable bit for a directory has a slightly different meaning than that of files. When a directory is marked executable, it means it is possible to change into that directory using cd(1). This also means that it is possible to access the files within that directory, subject to the permissions on the files themselves.

In order to perform a directory listing, the read permission must be set on the directory. In order to delete a file that one knows the name of, it is necessary to have write and execute permissions to the directory containing the file.

There are more permission bits, but they are primarily used in special circumstances such as setuid binaries and sticky directories. For more information on file permissions and how to set them, refer to chmod(1).

4.3.1. Symbolic Permissions

Contributed by Tom Rhodes.

Symbolic permissions use characters instead of octal values to assign permissions to files or directories. Symbolic permissions use the syntax of (who) (action) (permissions), where the following values are available:

OptionLetterRepresents
(who)uUser
(who)gGroup owner
(who)oOther
(who)aAll (world)
(action)+Adding permissions
(action)-Removing permissions
(action)=Explicitly set permissions
(permissions)rRead
(permissions)wWrite
(permissions)xExecute
(permissions)tSticky bit
(permissions)sSet UID or GID

These values are used with chmod(1), but with letters instead of numbers. For example, the following command would block other users from accessing FILE:

% chmod go= FILE

A comma separated list can be provided when more than one set of changes to a file must be made. For example, the following command removes the group and world write permission on FILE, and adds the execute permissions for everyone:

% chmod go-w,a+x FILE

4.3.2. FreeBSD File Flags

Contributed by Tom Rhodes.

In addition to file permissions, FreeBSD supports the use of file flags. These flags add an additional level of security and control over files, but not directories. With file flags, even root can be prevented from removing or altering files.

File flags are modified using chflags(1). For example, to enable the system undeletable flag on the file file1, issue the following command:

# chflags sunlink file1

To disable the system undeletable flag, put a no in front of the sunlink:

# chflags nosunlink file1

To view the flags of a file, use -lo with ls(1):

# ls -lo file1
-rw-r--r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1

Several file flags may only be added or removed by the root user. In other cases, the file owner may set its file flags. Refer to chflags(1) and chflags(2) for more information.

4.3.3. The setuid, setgid, and sticky Permissions

Contributed by Tom Rhodes.

Other than the permissions already discussed, there are three other specific settings that all administrators should know about. They are the setuid, setgid, and sticky permissions.

These settings are important for some UNIX® operations as they provide functionality not normally granted to normal users. To understand them, the difference between the real user ID and effective user ID must be noted.

The real user ID is the UID who owns or starts the process. The effective UID is the user ID the process runs as. As an example, passwd(1) runs with the real user ID when a user changes their password. However, in order to update the password database, the command runs as the effective ID of the root user. This allows users to change their passwords without seeing a Permission Denied error.

The setuid permission may be set by prefixing a permission set with the number four (4) as shown in the following example:

# chmod 4755 suidexample.sh

The permissions on suidexample.sh now look like the following:

-rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh

Note that a s is now part of the permission set designated for the file owner, replacing the executable bit. This allows utilities which need elevated permissions, such as passwd(1).

Note:

The nosuid mount(8) option will cause such binaries to silently fail without alerting the user. That option is not completely reliable as a nosuid wrapper may be able to circumvent it.

To view this in real time, open two terminals. On one, type passwd as a normal user. While it waits for a new password, check the process table and look at the user information for passwd(1):

In terminal A:

Changing local password for trhodes Old Password:

In terminal B:

# ps aux | grep passwd
trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd

Although passwd(1) is run as a normal user, it is using the effective UID of root.

The setgid permission performs the same function as the setuid permission; except that it alters the group settings. When an application or utility executes with this setting, it will be granted the permissions based on the group that owns the file, not the user who started the process.

To set the setgid permission on a file, provide chmod(1) with a leading two (2):

# chmod 2755 sgidexample.sh

In the following listing, notice that the s is now in the field designated for the group permission settings:

-rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh

Note:

In these examples, even though the shell script in question is an executable file, it will not run with a different EUID or effective user ID. This is because shell scripts may not access the setuid(2) system calls.

The setuid and setgid permission bits may lower system security, by allowing for elevated permissions. The third special permission, the sticky bit, can strengthen the security of a system.

When the sticky bit is set on a directory, it allows file deletion only by the file owner. This is useful to prevent file deletion in public directories, such as /tmp, by users who do not own the file. To utilize this permission, prefix the permission set with a one (1):

# chmod 1777 /tmp

The sticky bit permission will display as a t at the very end of the permission set:

# ls -al / | grep tmp
drwxrwxrwt 10 root wheel 512 Aug 31 01:49 tmp

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.

Send questions about this document to <freebsd-doc@FreeBSD.org>.