Permissions

Overview

A huge component of the command line environment that we've mostly ignored up until this point is your user account. When you open up Terminal or otherwise connect to a server, you are logging in to the command line. Your user account determines which directory you are put in when you connect, and it also determines what permissions and access you have to files and directories. Everything we've talked about up to this point is files, directories, executables, and the environment. Permissions are no different; they are based in the file system and depend on the user account for context.

Note: Permissions can be confusing. Don't get discouraged, though! A basic understanding of permissions can get you a long way. After reading through this chapter, make sure you do all the exercises to solidify the concepts discussed here.

In Unix and Linux file systems, permissions are divided into two parts: ownership and access types. There are three levels of ownership: user, group, and other; and three access types: read, write, and execute. Each level of ownership can be granted any or all of the access types, which brings the total number of permission combinations to 29, or 512. Luckily, it's very easy to see what permissions a file or directory has, and also pretty easy to modify its permissions.

Interpreting Permissions

In order to understand permissions better, let's think about a VIP lounge at the airport. Many people have access to the VIP lounge: airport staff, custodians and, of course, VIP members. The lounge has an owner—Acme Airline, for example—that has full access and control. There's an implied permission level for the general public as well (they cannot enter the VIP lounge). Once inside the lounge, there may be more access points that have different permission levels. The custodian's closet, for example, will be locked so that only custodians have access to it. Custodians, in turn, probably aren't supposed to drink the "free" beverages or otherwise use items reserved for the VIP members.

Let's represent the VIP lounge in terms of a file structure (note that tree is a command that displays a directory and its sub-directories):

$ tree airport/
airport/
└── vip_lounge
    ├── coffee
    ├── custodian_closet
    ├── donut
    └── internet_access

If we were to run ls with flags -lah on that file structure, we'd probably get something like the following (Remember that .. means "the parent directory," so in this case it refers to the airport/ directory.):

$ ls -lah vip_lounge
total 0
drwxr-x---  6 acmeair  vip        204B Jul 14 15:24 .
drwxr-xr-x  7 acmeair  public     238B Jul 14 15:23 ..
-rw-r-----  1 acmeair  vip          0B Jul 14 15:23 coffee
drwxrwx---  2 acmeair  acmeair     68B Jul 14 15:23 custodian_closet
-rw-r-----  1 acmeair  vip          2B Jul 14 15:24 donut
-rwxr-----  1 acmeair  vip         1GB Jul 14 15:24 internet_access

As mentioned above, permissions have three access types: read (r), write (w), and execute (x). Both files and directories have access types assigned to them, and each can be assigned a user and a group. The "other" level of ownership always includes everyone else implicitly. It looks like this:

  • A file or directory has:
    • an owner + owner's rwx access levels
    • a group + group's rwx access levels
    • other's rwx access levels

In the vip_lounge example above, you can see to the left of each file a string of characters that starts with a dash (which can also be a d to indicate a directory), then 9 more characters consisting of r ("read"), w ("write and delete"), x ("execute"), and - ("permission not granted"). Where a letter exists, that access type is granted, and where the dash exists, that permission is not granted.

After the string of d, rs, ws, xs, and dashes in the first item in the list, you can see acmeair vip. These two strings represent the user and group assigned to the file or directory. In this case, the name of the user is "acmeair" and the name of the group is "vip".

The following chart shows what each part of the permissions represents. Each of the first 10 characters can be replaced with a dash to show that access level is not granted or, in the case of the d, that the object in question is not a directory. Let's take a look at a diagram to make this a bit easier to understand:

# +-------- Directory or not
# |  +------- User Read, Write, Execute
# |  |   +------- Group Read, Write, Execute
# |  |   |   +----- Other Read, Write, Execute
# |  |   |   |   +--- The name of the user
# |  |   |   |   |     +--- The name of the group
# |  |   |   |   |     |
# d|rwx|rwx|rwx user group

Now that we understand how the permissions are laid out, we can interpret the output of the ls -lah command we ran previously. If you look at the first item displayed, the . directory (also vip_lounge), we can gather the following:

  • d: It is a directory.
  • rwx: Its user has read, write, and execute access.
  • r-x: Its group has read and execute access.
  • ---: Other has no access.
  • The user named "acmeair" has been assigned to it.
  • The group called "vip" has been assigned to it.

In practice, this means the directory's default permissions allow files to be read or executed by user "acmeair" or any member of the "vip" group, but nobody else has access.

Note that the permissions for the parent directory (..) are a little different. In particular, the group permissions are for the group called "public", and the "other" permissions allow reading and executing by anybody.

In this hypothetical file system, the vip group would have multiple users associated with it, such as acmeair, bob, jeff, etc. Let's pretend that the following users exist and belong to the groups listed beneath them (we'll be talking about groups more in a later section):

$ groups bob
bob vip
$ groups acmeair
acmeair vip
$ groups jeff
jeff acmeair

In this scenario, anyone that belongs to the vip group would have group access to anything that has read permissions set for the vip group. The user bob, based on his groups as listed above, would have the ability to enter the vip_lounge directory and partake of (i.e. read) its donut, coffee, and internet access content. The bob user, however, wouldn't have access to enter the custodian_closet content or use its contents, but jeff and acmeair would.

An important thing to note from the above example is that the permissions are not bestowed upon the user or groups. Rather, the files and directories are assigned groups and users, with particular permission levels for those. It's kind of like a reservation at a restaurant table. There's nothing about a person that inherently gives them permission to dine at a restaurant at a particular table and at a particular time. It's because the restaurant has labeled, or set apart, that table for that time that the person is able to dine there. So it is with the file system. There's nothing inherently special about any group or user (except the root user). A user's privileges are defined by the files and directories themselves.

Setting Permissions

There are a few ways of setting the permissions on a file or directory. The chmod (Change Mode) command will be your friend here. To add write permissions to a file, for example, you can do something like this:

$ chmod +w sample.txt

The +w means "add write access." If you want to get more granular in how you set permissions on a file or directory, you can prefix the permission with u, g, o, or a, which stand for "user (owner)", "group", "other", and "all", respectively:

$ ls -lah test.txt
-rwxr--r--  1 bob  staff  1GB Jul 14 15:24 test.txt

$ # Remove write access for user
$ chmod u-w test.txt
$ ls -lah test.txt
-r-xr--r--  1 bob  staff  1GB Jul 14 15:24 test.txt

$ # Add execute access for group
$ chmod g+x test.txt
$ ls -lah test.txt
-r-xr-xr--  1 bob  staff  1GB Jul 14 15:24 test.txt

What if you want to set access level permissions for the user, group, and other all at once? You can do so with 3 numbers, each from 0 to 7. Why 0-7? There are 23 (which is 2 * 2 * 2, or 8) permission levels. When you count from 0 to 7, there are actually eight numbers. Note that it's really common in computer languages to count starting from zero rather than 1. In this octal system, execute, write, and read permissions each add 1, 2, and 4 respectively, resulting in non-ambiguous designations of permissions. In short, here are the different combinations of permissions based on the octal mask.

The following table shows what access level each number represents:

Number Permission
0 No permission granted.
1 Can execute.
2 Can write.
3 Can write and execute (2 + 1 = 3).
4 Can read.
5 Can read and execute (4 +1 = 5).
6 Can read and write (4 + 2 = 6).
7 Can read and write and execute (4 + 2 + 1 = 7).

If you combine the permissions from the table above—one each for owner, group, and other—you can define the whole set of permissions for a file or directory:

$ chmod 777 test.sh

$ ls -l test.sh
-rwxrwxrwx  1 bob admin 0B Jul 15 15:24 test.sh

$ chmod 000 test.sh

$ ls -l test.sh
----------  1 bob admin 0B Jul 15 15:24 test.sh

$ chmod 754 test.sh

$ ls -l test.sh
-rwxr-xr--  1 bob admin 0B Jul 15 15:24 test.sh

Note: in order to change the permissions of a file or directory, you must be its owner, be root, or use sudo. See the Root User and Sudo section below.

Users and Groups

We know that a user and a group are assigned to all files and directories in Linux and Unix systems, and it is pretty obvious that if your user is assigned to a file, you will have the ability to read, write, or execute the file according to the access types granted. But how do groups work? Users can belong to multiple groups, and groups can have multiple users. Users will have access to files and directories based on the groups to which the users belong. So, in our ls -lah example above, the file named "donut.txt" can be read (or consumed!) by any user in the "vip" group.

To determine if your user is part of a certain group, use the groups command:

$ groups
ubuntu adm dialout cdrom floppy sudo audio dip video plugdev netdev

In the above example, the "ubuntu" user is part of several groups, the first being a group of the same name as the user: "ubuntu".

Root User and Sudo

In Unix and Linux systems, there is a special user called "root." The root user is the super user—it can read, write, and delete any file. If the "acmeair" user is like an airline company, then the root user is basically a god. Because the root user has so much power, it is a common recommendation to not log in as root, and to only run commands with root when necessary. If you are logged in as a non-root user and know the root user's password, you can switch to the root user account at any time with the following command:

$ su -
Password:

If you put in the above command, you will be required to put in the root user's password. Note: you may not have root access if you are using a managed server environment.

Depending on your local configuration, account privileges, and when you last used sudo, you may not be asked for your password. It's not an error if you aren't asked for your password.

Although the root user can read, write, and delete (almost) any file, it cannot execute just any file. As mentioned in the chapter "Files, Directories, and Executables", a file can only be executed if it has the execute permission granted. In the case of the root user, it doesn't matter who the permission is granted to; as long as it is granted to the user, the group, or other, root can execute it.

Sudo

While you will be able to log in as root directly in some scenarios, it is more common to use the sudo command to perform actions that require root privileges. You can think of it as borrowing the god-like powers of the root user for a moment. The sudo command allows you to "do" something as a "super user." When you use this command, you will usually be required to input a password; but instead of the root user's password, you'll be putting in your own password. The following is an example of a command that requires root privileges, but that can be run using sudo (don't run this unless you want your computer to reboot!):

sudo reboot

But why use sudo instead of just logging in as root? There are several reasons for doing this, including the following:

  • The server administrator wants you to have root access for some commands and/or directories, but not for everything. In this case the administrator will set up sudo to have restrictions or allow-listed commands.
  • Running commands while logged in as root can be dangerous. Using a non-root user makes it obvious when you are running a command that requires root privileges because you have to prefix your command with sudo.
  • The sudo command provides a detailed audit trail so that system administrators can track what commands individuals used on system files.
  • Sudo uses a ticketing system where you put in your password once, then you don't have to until you haven't run any sudo commands for five minutes or longer. This adds security to your command line session, preventing others from gaining root access if you leave your Terminal open on accident.

Summary

File system permissions are complicated, and are probably one of the biggest sources of headaches for command line beginners. But having a basic understanding of how permissions work will get you a long way. Remember:

  • Permissions are assigned to files and directories—not users and groups.
  • Access levels are determined by the rwx (read, write, execute) permissions for the owner, group, and other.
  • A file must have the x (execute) permission to execute that file directly.
  • To change the permissions of a file or directory, you either must be logged in as that file's owner or the root user, or you must use the sudo command.

With an understanding of the above, you'll be able to resolve many issues that you will surely run into while programming.

Exercises

  1. Which user and group are assigned to the /etc folder on your computer?

    Solution

    You can find the user and group of the /etc folder by running the following command:

    $ ls -l /
    

    The above command will list multiple files and directories, so just find the one for /etc. It should have the user root and probably the group root if you are on linux. If you run the same command on a Mac computer, the group for the /etc folder is probably wheel.

    Video Walkthrough

    Please register to play this video

  2. Which user and group are assigned to the $HOME folder?

    Solution

    If you type ls -la $HOME, you'll see a list of all the files and directories in your home folder. It will also show a directory called .. and one called .. Remember that a single . refers to the current directory, so that item is the listing for the $HOME directory. Your user should be its owner, and the group will either be the same name as your user, or staff, if you're on a Mac.

    You could also type ls -la $HOME/.. to list all the files and directories in the /home (Linux) or /Users (Mac) directory. The folder that's named the same as your username is your home directory.

    Video Walkthrough

    Please register to play this video

  3. What are mary's permissions for the napkins file in the following outputs?

    $ groups mary
    mary travelers vip
    $ ls -l custodian_closet
    total 0
    -rw-rw----  1 acmeair acmeair 0 Jul 21 17:57 napkins
    -rw-rw----  1 acmeair acmeair 0 Jul 21 17:57 paper_towels
    

    Solution

    The user mary doesn't have access because she doesn't belong to the acmeair group.

    Video Walkthrough

    The video for this exercise appears in Exercise 5.

  4. What are mary's permissions to the donuts file in the following example:

    $ groups
    mary travelers vip
    $ ls -l vip_lounge
    $ ls -l ./
    ...
    -rw-rw----  1 acmeair  vip  0 Jul 21 17:57 donuts
    ...
    

    Solution

    The user mary has read and write access to the donuts file.

    Video Walkthrough

    The video for this exercise appears in Exercise 5.

  5. What are mary's permissions to the laptop file in the following example? What are the permissions for the group acmeinc?

    $ ls -l vip_lounge
    ...
    -r-xrwx---  1 mary acmeinc 0 Jul 21 17:57 laptop
    ...
    

    Solution

    The user mary has read and execute permissions, and the group acmeinc has read, write, and execute permissions.

    Video Walkthrough

    Please register to play this video

  6. Practice using sudo to log in as root:

    $ cd
    $ sudo su
    Password:
    root@host:/home/ubuntu#
    

    Exit out of the root user session:

    root@host:/home/ubuntu# exit
    $
    

    Log in as root in root's home directory:

    $ sudo su -
    Password:
    root@host:~# exit
    $
    

    Run a command as root:

    $ ls /root
    ls: cannot open directory /root: Permission denied
    $ sudo ls /root
    Password:
    $
    

    Note: You may not get the same results on your computer when running the above command. Specifically, if you are on a Mac, you probably don't have a /root directory. The above is an example of what you may see in a typical Linux environment.

    Warning: The root user, and by extension the sudo command, can be very powerful. As such, be very careful when you use it, especially with commands like rm, as you could potentially delete your entire file system by accident.

    Video Walkthrough

    Please register to play this video