CHAPTER 6
Looking back at the long listings provided by the ls command, we can now decipher the permissions for a given file or directory listing. Permissions are displayed at the beginning of long listings.
$ ls -l sales.data |
The first character in the permissions string reveals the type. For example, - is a regular file, d is a directory, and l is a symbolic link. Those are the most common types you will encounter. However, there are other file types listed in the following table.
Symbol | File Type |
|---|---|
- | Regular file |
b | Block special file |
c | Character special file |
d | Directory |
l | Symbolic link |
p | FIFO (named pipe) |
s | Socket |
? | Some other file type |
The remaining characters in the permissions string represent the three main types of permissions: read, write, and execute. Each permission is represented by a single letter, also known as a symbol. Read is represented by r, write by w, and execute by x.
Symbol | Permission |
|---|---|
r | Read |
w | Write |
x | Execute |
For files as opposed to directories, read, write, and execute permissions have intuitive meanings. Read permissions allow you to view the contents of a file. Write permissions allow you to modify a file. Execute permissions allow you to run, or execute, a file as a program.
The meanings of the read, write, and execute permissions are not as intuitive when it comes to directories. Read permissions allow you to read the file names in a directory. Write permissions allow you to change the entries in a directory by renaming files, creating files, and deleting files. Execute permissions allow you to cd or change into the directory. Review the following differences between file and directory permissions.
Directory Meaning | File Meaning | Permission |
|---|---|---|
Allows file names in the directory to be read. | Allows a file to be read. | Read |
Allows entries within the directory to be modified. | Allows a file to be modified. | Write |
Allows access to the contents and metadata of entries within the directory. | Allows the execution of a file. | Execute |
All files in Linux are owned by a user and a group. This allows for unique permissions to be applied across three sets of users: the user owner, the group owner, and others. When modifying permissions, these sets can be represented by a single letter: u for the user owner, g for the group owner, and o for others. In addition, the letter a can represent all three of these permissions groups. Note that these characters do not show up in an ls listing, but they can be used when changing permissions.
Symbol | Category |
|---|---|
u | User |
g | Group |
o | Other |
a | All |
Going back to our original example, we can view the user and group owner of the file sales.data. The user owner is listed first, followed by the group owner. In this case, jason is the user owner, and users is the group owner.
$ ls -l sales.data |
Every user is a member of at least one group, called their primary group. However, users can be members of many groups. Groups are used to organize users into logical sets. For example, a group named sales might be created and contain all the employees from the sales department. You could then set a file’s group owner as the sales group, and allow members of the sales group read and write permissions to the file, or any other set of permissions for that matter.
To determine what groups you are a member of, run the groups command. If you supply another user’s ID as an argument to the groups command, you will see the list of groups to which that user belongs. You can also run id -Gn [user] to get the same result.
$ groups |
Now you have enough background information to start decoding permissions strings. The first character in the permissions string is the type. The next three characters represent the permissions available to the user, also known as the owner of the file. The next three characters represent the permissions available to the group. The last three characters represent the permissions available to all others.
In this case, order has meaning. Permission groups will always be displayed in this order: user, group, and others. Within these three permission groups, permission types will always be in this order: read, write, and execute. If a particular permission type is not granted, then a hyphen (-) will take its place.
Here is a colorized representation of the permission information displayed by ls -l. The file type is highlighted in red, the user permissions in green, the group permissions in blue, and the other permissions in purple.
$ ls -l sales.data |
By examining the preceding example, you can determine that the file type is a regular file (-), the user owner is allowed read and write permissions (rw-), the group owner is granted read permissions (r--), and others are allowed read permissions as well (r--). The user owner is jason, and the group owner is users.
If there happens to be an additional character at the end of the permissions string, an alternative access control method has been applied. A trailing period (.) means that a SELinux (Security-Enhanced Linux) security context has been applied to the file or directory. A trailing plus sign (+) means that ACLs (Access Control Lists) are in use. SELinux and ACLs are beyond the scope of this book. However, you will be pleased to know that the use of these is rare. If you are having issues with permissions, look for an additional trailing character in the permissions string. If one is present be aware that further investigation may be necessary.
$ ls -l sales.data.selinux |
Permissions are also known as modes. The command chmod, which is short for "change mode," is used to change permissions. The format of the chmod command is chmod mode file. There are two ways to specify the mode. The first way is called symbolic mode. The symbolic mode format is chmod user_category operator permission. Here is a table view of the chmod command using the symbolic mode format.
Description | Symbol |
|---|---|
The change mode command itself. | chmod |
The user category. Use one or more of u for user, g for group, o for other, a for all. | ugoa |
One of +, -, or =. Use + to add permissions, - to subtract them, or = to explicitly set them. | +-= |
The actual permissions. Use one or more of r for read, w for write, and x for execute. | rwx |
You can add, subtract, or set permissions using user category and permission pairs. For example, if you want to add the write permission for the group owner, you would specify chmod g+w file.
$ ls -l sales.data |
After running chmod g+w sales.data, the permissions string changed from -rw-r--r-- to -rw-rw-r--. Remember that the permissions are displayed in the order of user, group, and other. The group permission set now includes the w symbol, indicating that the write permission has been granted. Now jason, the owner of the file, and members of the users group can read and write to the sales.data file. The following example demonstrates how to subtract the write permission.
$ ls -l sales.data |
Multiple permissions can be changed at once. For example, you can add write and execute permissions for the group owner by using g+wx.
$ ls -l sales.data |
You can also modify multiple permissions groups at once. For example, ug+wx will add write and execute permissions for the user and group owners if they don’t already have them. In this case, notice that the user owner already had write permission before the chmod command was executed. After running chmod, the user owner will still have write permissions, as well as the newly added execute permissions. Using + to add permissions will always add permissions, if applicable. It never takes them away.
$ ls -l sales.data |
If you want to set different permissions for different user categories, you can separate the specifications with a comma. You can mix and match to produce the permissions you desire. For example, u=rwx,g+x will set the read, write, and execute permissions for the file owner while adding the execute permission for the group. See how the permissions change for sales.data in the following example.
$ ls -l sales.data |
If you want to set the file to be readable, and only readable, by everyone, run chmod a=r file. When you use the equal sign (=), the current permissions are replaced by what is specified. In this case, a=r sets the read permission for user, group, and other. Any write or execute permissions will be removed.
$ ls -l sales.data |
If you do not specify permissions following the equal sign, the permissions are removed. Here is an illustration of this behavior.
$ ls -l sales.data |
The second way to specify modes with the chmod command is called octal mode. Understanding symbolic mode will help you learn octal mode. Some Linux users never move beyond symbolic permissions. However, experienced Linux users find using octal mode quicker and easier in the long term because there are only a few commonly used permissions which can be readily memorized and recalled.
Octal mode permissions are based on the binary numeral system, also known as the base-2 numeral system. Each permission type is treated as a bit that is either set to off, represented by a zero (0), or on, represented by a one (1). In permissions, order has meaning. Permissions are always in read, write, and execute order. If r, w, and x are all set to off, the binary representation is 000. If they are all set to on, the binary representation is 111. To represent read and write permissions while omitting execute permissions, the binary number is 110.
Execute | Write | Read | |
|---|---|---|---|
0 | 0 | 0 | Binary and decimal value for off. |
1 | 1 | 1 | Binary value for on. |
1 | 2 | 4 | Decimal value for on. |
Supply the chmod command with the base-10, or decimal, value of the desired permissions. To convert the binary representation into decimal, remember that read equals 4, write equals 2, and execute equals 1. The permissions number is determined by adding up the values for each permission type. For example, read and execute permissions are represented by 5 because 4 for read, plus 1 for execute, equals 5. There are eight possible values from zero to seven, hence the name octal mode. The following table demonstrates all eight of the possible permissions.
Octal | Binary | String | Permissions |
|---|---|---|---|
0 | 000 | --- | No permissions |
1 | 001 | --x | Execute only |
2 | 010 | -w- | Write only |
3 | 011 | -wx | Write and Execute |
4 | 100 | r-- | Read only |
5 | 101 | r-x | Read and Execute |
6 | 110 | rw- | Read and Write |
7 | 111 | rwx | Read, Write, and Execute |
Remember that in permissions order has meaning. The user categories are always in this order: user, group, and other. Once the octal value is determined for each category, it must be specified in that order. For example, to get -rwxr-xr—permissions, run chmod 754 file. That means the owner of the file has read, write, and execute permissions; the members of the file's group have read and execute permissions; and others only have read permissions.
Other | Group | User | |
|---|---|---|---|
r-- | rw- | rwx | Symbolic |
100 | 110 | 111 | Binary |
4 | 6 | 7 | Decimal |
The following table illustrates the most commonly used permissions. These five permission sets will cover most permission situations.
Symbolic | Octal | Meaning |
-rwx------ | 700 | Allows the file's owner full control over the file. No others on the system have access. |
-rwxr-xr-x | 755 | Allows everyone on the system to execute the file but only the owner can edit it. |
-rw-rw-r-- | 664 | Allows a group of people to modify the file and let others read it. |
-rw-rw---- | 660 | Allows a group of people to modify the file and not let others read it. |
-rw-r--r-- | 644 | Allows everyone on the system to read the file but only the owner can edit it. |
Many times newcomers to the Linux operating system err on the side of permissive permissions. Instead of thinking through the required permissions they sometimes grant "everything to everybody" by using 777 or 666 permissions. Whenever you see a file or directory with 777 or 666 permissions, know that there is almost always a better permission set that can be used.
Granting unnecessary privileges to a file or directory not only has security implications, but it can also invite unwanted changes to those files or directories. If a file has 777 permissions, then anyone on the Linux system can edit that file. This can lead to a situation where someone accidentally saves changes to a file when all they really wanted to do was view the file's contents with an editor.
Also, a user on the system could purposefully use the weak permissions to escalate privileges, gain access to data they shouldn't see, or even destroy data. They could potentially insert malicious code into a script or program and wait for it to be executed by someone else on the system. Remember that anyone on the system can execute the file because all permissions, including the execute permission, have been granted.
If multiple people require write access to a file, make use of groups and limit the access of others. Consider it a best practice to avoid using 777 and 666 permission modes.
Let's look at a situation where multiple people need access to the same file. For example, if the members of a sales team need to update a file named sales.report, the group owner of the file could be set to the Linux group named sales by using the chgrp command. Next, the permissions could be set to 664 (rw-rw-r--) or even 660 (rw-rw---) if you do not want others on the system to be able to read the file. Technically, 774 (rwxrwxr--) or 770 (rwxrwx---) permissions also work, but since sales.report is not an executable program, it makes more sense to use 664 (rw-rw-r--) or 660 (rw-rw----).
When a file is created, it is set to the current user's primary group. You can override this behavior by using the newgrp command, but remember by default a new file will inherit your default group. In the following example, Jason's primary group is users. The format of the chgrp command is chgrp GROUP FILE.
$ nano sales.report |
Sharing files from within individual user's home directories can be confusing. It's often easier to keep shared data in a shared location. If you have superuser privileges, you could create a /usr/local/sales directory for the sales team. If you don't have such permissions you can ask the system administrator to create that directory for you. The group owner of the shared directory should be set to sales and the permissions should be set to 775 (rwxrwxr-x) or 770 (rwxrwx---). Use 770 (rwxrwx---) if no one outside the sales team should have access to any files, directories, or programs located in /usr/local/sales.
$ ls -ld /usr/local/sales |
A common problem encountered by Linux newcomers is incorrect directory permissions. Directory permissions usually only contain 0s, 5s, and 7s. Common directory permissions include 755, 700, 770, and 750. Incorrect directory permissions can prevent file access and file execution. If you determine that a file's permissions have been set correctly, look at the parent directory’s permissions. Work your way toward the root of the file system by running ls -ld . in the current directory, moving up to the parent directory with cd .., and repeating those two steps until you find the problem.
$ ls -ld directory/ |
The file creation mask, also known as the umask, determines the default permissions of new files and directories. The umask is typically set by the system administrator; however, an individual user may override the setting by including a umask statement in his or her account's initialization files.
If no mask is applied, new directories receive 777 (rwxrwxrwx) permissions and new files receive 666 (rw-rw-rw-) permissions. When the umask is applied to these base permissions, it disables, or masks, certain permissions. For example, a umask of 000 will disable, or mask, zero bits. In this case, new directories receive 777 permissions and new files receive 666 permissions. At the other extreme, a umask of 777 disables all permissions bits. New files and directories receive 000 permissions in this instance.
umask [-S] [mode] Sets the file creation mask to a mode if specified. If a mode is omitted, the current mode will be displayed. Using the -S argument allows umask to display or set the mode with symbolic notation.
A quick way to estimate how a umask mode affects default permissions is to subtract the octal umask mode from 777 in the case of directories, or 666 in the case of files. The following is an example of a 022 umask, which is typically the default umask used by Linux distributions or set by system administrators.
Directory | File | |
|---|---|---|
777 | 666 | Base Permission |
-022 | -022 | Subtract the umask |
755 | 644 | Creation Permission |
Using a umask of 002 is ideal for working with members of your group. When files or directories are created, the permissions allow members of the group to manipulate those files and directories.
Directory | File | |
|---|---|---|
777 | 666 | Base Permission |
-002 | -002 | Subtract the umask |
775 | 664 | Creation Permission |
Here is another possible umask to use for working with members of your group. By using 007, no permissions are granted to users outside of the group.
Directory | File | |
|---|---|---|
777 | 666 | Base Permission |
-007 | -007 | Subtract the Umask |
770 | 660 * | Creation Permission |
Again, using this octal subtraction method is a good estimation. You can see that the method breaks down with the umask mode of 007. In reality, to get an accurate result each time, you need to convert the octal permissions into binary values. From there, you use a bitwise NOT operation on the umask mode and then perform a bitwise AND operation against that and the base permissions. Another way to think of this is that the umask disables the values specified. A umask of 007 effectively means "disable all of the bits for the other users." A umask of 022 means "disable the write bits for the group and others."
The following table contains all the resulting permissions created by each one of the eight mask settings. Note that the most common and practical umask modes to use are 022, 002, 077, and 007.
Octal | Binary | Directory Permissions | File Permissions |
|---|---|---|---|
0 | 000 | rwx | rw- |
1 | 001 | rw- | rw- |
2 | 010 | r-x | r-- |
3 | 011 | r-- | r-- |
4 | 100 | -wx | -w- |
5 | 101 | -w- | -w- |
6 | 110 | --x | --- |
7 | 111 | --- | --- |
When the umask command is queried for the current setting, it returns four characters instead of three. The following example shows the umask being clearly set to 002, but umask returns 0022.
$ umask 022 $ umask |
Until now, you have only been introduced to permissions for user, group, and other. However, there is a class of special modes called setuid, setgid, and sticky. These special modes are declared by prepending a character to the octal mode that you normally use with umask or chmod. The important point here is to know that umask 022 is the same as umask 0022. Likewise, chmod 644 is the same as chmod 0644.
The setuid permission allows the program to run as the owner of the file, not the user executing it. One example of where this permission is used is with the passwd command. The passwd command allows a user to change his or her own password, but it requires superuser privileges to modify the /etc/passwd and /etc/shadow files.
Prepend the number 4 when using octal mode to enable the setuid permission. For symbolic mode, use u+s.
$ ls -ld /usr/bin/passwd -rwsr-xr-x 1 root root 47032 Jul 26 2013 /usr/bin/passwd $ chmod 4555 script $ ls -l script -r-sr-xr-x. 1 jason users 0 Jun 7 18:11 script |
Similar to the setuid permission, the setgid permission allows a program to run with the group of the file, not the group of the user executing it. A Linux command that uses such a permission is the locate command.
When the setgid is used on a directory, it causes new entries in that directory to be created with the same group as the directory. When working with groups, using setgid on shared directories can prevent someone from accidentally creating a file in their default group instead of the intended group.
Prepend the number 2 when using octal mode to enable the setgid permission. For symbolic mode, use g+s.
$ ls -l /usr/bin/locate -rwx--s--x 1 root slocate 35548 Oct 10 2012 /usr/bin/locate $ chmod 2555 script $ ls -l script -r-xr-sr-x 1 jason users 0 Jun 7 18:28 script $ mkdir salesdir $ chgrp sales salesdir $ chmod g+rwx salesdir $ ls -ld salesdir/ drwxrwxr-x 2 jason sales 4096 Jun 7 18:29 salesdir/ $ touch salesdir/file-before-setgid $ ls -l salesdir/ total 0 -rw-r--r-- 1 jason users 0 Jun 7 18:29 file-before-setgid $ chmod g+s salesdir $ ls -ld salesdir drwxrwsr-x 2 jason sales 4096 Jun 7 18:29 salesdir $ touch salesdir/file-after-setgid $ ls -l salesdir/ total 0 -rw-r--r-- 1 jason sales 0 Jun 7 18:30 file-after-setgid -rw-r--r-- 1 jason users 0 Jun 7 18:29 file-before-setgid $ |
The sticky bit prevents one user from deleting another user's files even if he or she would normally have permission to do so. The most common place you will see the sticky bit employed is on the /tmp and /var/tmp directories.
Prepend the number 1 when using octal mode to enable the sticky bit. For symbolic mode, use +t.
$ ls -ld /tmp drwxrwxrwt 11 root root 20480 Jun 6 18:17 /tmp $ ls -ld /var/tmp drwxrwxrwt 4 root root 4096 Jun 7 16:46 /var/tmp $ chmod 1777 tmp $ ls -ld tmp drwxrwxrwt 2 jason users 4096 Jun 7 16:50 tmp |
Octal | Permission |
|---|---|
1 | sticky bit |
2 | setgid |
4 | setuid |
In the following example, new files and directories are created after setting the umask. Notice that the default file and directory permissions depend on the umask setting.
$ umask |