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.
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:
Value | Permission | Directory Listing |
---|---|---|
0 | No read, no write, no execute | --- |
1 | No read, no write, execute | --x |
2 | No read, write, no execute | -w- |
3 | No read, write, execute | -wx |
4 | Read, no write, no execute | r-- |
5 | Read, no write, execute | r-x |
6 | Read, write, no execute | rw- |
7 | Read, write, execute | rwx |
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. 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).
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:
Option | Letter | Represents |
---|---|---|
(who) | u | User |
(who) | g | Group owner |
(who) | o | Other |
(who) | a | All (“world”) |
(action) | + | Adding permissions |
(action) | - | Removing permissions |
(action) | = | Explicitly set permissions |
(permissions) | r | Read |
(permissions) | w | Write |
(permissions) | x | Execute |
(permissions) | t | Sticky bit |
(permissions) | s | Set 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
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 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.
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.
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, start the passwd process as a normal user. While it waits for a new password, check the process table and look at the user information for passwd:
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
As stated above, the passwd is run by a normal user, but 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 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