Setting permissions on files and directories
In this section, all the user management we've done in this chapter so far all comes together. We've learned how to add accounts, manage accounts, and secure them, but we haven't actually done any work regarding managing the resources as far as who is able to access them. In this section, I'll give you a brief overview of how permissions work in Ubuntu Server and then I'll provide some examples for customizing them.
Viewing permissions
I'm sure by now that you understand how to list the contents of a directory with the ls
command. When it comes to viewing permissions, the -l
flag is especially handy, as the output that the long listing provides allows us to view the permissions of an object:
ls -l
The following are some example, hypothetical file listings:
-rw-rw-rw- 1 doctor 5 Jan 11 12:52 welcome
-rw-r--r-- 1 root root 665 Feb 19 2014 profile
-rwxr-xr-x 1 dalek dalek 35125 Nov 7 2013 exterminate
In each line, we see several fields of information. The first column is our permission string for the object (for example, -rw-r—r--
), which we'll cover in more detail shortly. We also see the link count for the object (second column). Links are beyond the scope of this chapter but will be discussed in Chapter 5, Managing Files and Directories. Continuing on, the user that owns the file is displayed in the third column, the group that owns the file is in the fourth column, the size in bytes is in the fifth, the last date the file was modified is in the sixth, and finally there is the name of the file.
Keep in mind that depending on how your shell is configured, your output may look different and the fields may be in different places. For the sake of our discussion on permissions, what we're really concerned with is the permissions string, as well as the owning user and group. In this case, we can see that the first file (named welcome
) is owned by a user named doctor
. The second file is named profile
and is owned by root
. Finally, we have a file named exterminate
owned by a user named dalek
.
With these files, we have the permission strings of -rw-rw-rw-
, -rw-r--r--
, and -rwxr-xr-x
respectively. If you haven't worked with permissions before, these may seem strange, but it's actually quite easy when you break them down. Each permission string can be broken down into four groups, as I'll show you in the following table:
Object type |
User |
Group |
World |
- |
|
|
|
- |
|
|
|
- |
|
|
|
I've broken down each of the three example permission strings into four groups. Basically, I split them each at the first character and then again every third. The first section of a permission string is just one character. In each of these examples, it's just a single hyphen. This refers to what type the object is. Is it a directory? A file? A link? In our case, each of these permission strings is a file, because the first positions of the permission strings are all hyphens. If the object were a directory, the first character would've been a d
instead of a -
. If the object were a link, this field would've been l
(lowercase L) instead.
In the next section, in the second column of each object, we have three characters, rw-
, rw-
, and rwx
respectively. This refers to the permissions that apply to the user that owns the file. For example, here is the first permission string again:
-rw-rw-rw- 1 doctor doctor 5 Jan 11 12:52 welcome
The third section of the preceding code output shows us that doctor
is the user that owns the file. Therefore, referring back to the table, the second column of the permission string (rw-
) applies specifically to the user doctor
. Moving on, the third column of permissions is also three characters; in this case, rw-
again. This section of the permissions string refers to the group that owns the file. In this case, the group is also named doctor
, as you can see in column four of the preceding code output. Finally, the last section of the permission string, visualized in the table (rw-
yet again, in this case), refers to world, also known as other. This basically refers to anyone else other than the owning user and owning group. Therefore, literally everyone else gets at least rw-
permissions on the object.
Individually, r
stands for read and w
stands for write. Therefore, we can read the second column (rw-
), indicating that the user (doctor
) has access to read and write to this file. The third column (rw-
again) tells us the doctor
group also has read and write access to this file. The fourth column of the permission string is the same, so anyone else would also have read and write permissions to the file as well.
The third permission string I gave as an example looks a bit different. Here it is again:
-rwxr-xr-x 1 dalek dalek 35125 Nov 7 2013 exterminate
Here, we see the x
attribute set. The x
attribute refers to the ability to execute the file as a script. So, with that in mind, we know that this file is likely a script and is executable by users, groups, and others. Given the filename of exterminate
, this is rather suspicious, and if it were a real file, we'd probably want to look into it.
If a permission is not set, it will simply be a single hyphen where there would normally be r
, w
, or x
. This is the same as indicating that a permission is disabled. Here are some examples:
rwx
: Object has read, write, and execute permissions set for this fieldr-x
: Object has read enabled, write disabled, and execute enabled for this fieldr--
: Object has read enabled, write disabled, and execute disabled for this field---
: Object has no permissions enabled for this field
Bringing this discussion all the way home, here are a few more permission strings:
-rw-r--r-- 1 sue accounting 35125 Nov 7 2013 budget.txt
drwxr-x--- 1 bob sales 35125 Nov 7 2013 annual_projects
For the first of these examples, we see that sue
is the owning user of budget.txt
and that this file is assigned an accounting group. This object is readable and writable by sue
and readable by everyone else (group and world). This is probably bad, considering this is a budget file and is probably confidential. We'll change it later.
The annual_projects
object is a directory, which we can tell from the d
in the first column. This directory is owned by the bob
user and the sales
group. However, since this is a directory, each of the permission bits has different meanings. In the following two tables, I'll outline the meanings of these bits for files and again for directories:
- Files:
Bit |
Meaning |
|
The file can be read |
|
The file can be written to |
|
The file can be executed as a program |
- Directories:
Bit |
Meaning |
|
The contents of the directory can be viewed |
|
Contents of the directory can be altered |
|
The user or group can use cd to go inside the directory |
As you can see, permissions are read differently depending on their context: whether they apply to a file or a directory. In the example of the annual_projects
directory, bob
has rwx
permissions to the directory. This means that the user bob
can do everything (view the contents, add or remove contents, and use cd
to move the current directory of his shell into the directory). Regarding a group, members of the sales
group are able to view the contents of this directory and cd
into it. However, no one in the sales
group can add or remove items to or from the directory. On this object, other has no permissions set at all. This means that no one else can do anything at all with this object, not even view its contents.
Changing permissions
So, now we understand how to read permissions on files and directories. That's great, but how do we alter them? As I mentioned earlier, the budget.txt
file is readable by everyone (other). This is not good because the file is confidential. To change permissions on an object, we will use the chmod
command. This command allows us to alter the permissions of files and directories in a few different ways.
First, we can simply remove read access from the sue
user's budget file by removing the read bit from the other field. We can do that with the following example:
chmod o-r budget.txt
If we are currently not in the directory where the file resides, we need to give a full path:
chmod o-r /home/sue/budget.txt
If you're using the chmod
command against files other than those you own yourself, you'll need to use sudo
.
But either way, you probably get the idea. With this example, we're removing the r
bit from other (o-r
). If we wanted to add this bit instead, we would simply use +
instead of -
. Here are some additional examples of chmod
in action:
chmod u+rw <filename>
: The object getsrw
added to theuser
columnchmod g+r <filename>
: The owning group is given read accesschmod o-rw <filename>
: Other is stripped of therw
bits
In addition, you can also use octal point values to manage and modify permissions. This is actually the most common method of altering permissions. I like to think of this as a scoring system. That's not what it is, but it makes it a lot easier to understand to think of each type of access as having its own value. Basically, each of the permission bits (r
, w
, and x
) has its own octal equivalent, as follows:
- Read:
4
- Write:
2
- Execute:
1
With this style, there are only a few possibilities for numbers you can achieve when combining these octal values (each can only be used once). Therefore, we can get 0
, 1
, 2
, 3
, 4
, 5
, 6
, and 7
by adding (or not adding) these numbers in different combinations. Some of them you'll almost never see, such as an object having write access but not read. For the most part, you'll see 0
, 4
, 5
, 6
, and 7
used with chmod
most often. For example, if we add Read
and Write
, we get 6
. If we add Read
and Execute
, we get 5
. If we add all three, we get 7
. If we add no permissions, we get 0
. We repeat this for each column (User
, Group
, and Other
) to come up with a string of three numbers. Here are some examples:
600
: User has read and write (4+2). No other permissions are set.This is the same as
-rw-------
.740
: User has read, write, and execute. Group has read. Other has nothing.This is the same as
-rwxr-----
.770
: Both user and group have full access (read, write, execute). Other has nothing.This is the same as
-rwxrwx---
.777
: Everyone has everything.This is the same as
-rwxrwxrwx
.
Going back to chmod
, we can use this numbering system in practice:
chmod 600 filename.txt
chmod 740 filename.txt
chmod 770 filename.txt
Hopefully you get the idea. If you wanted to change the permissions of a directory, the -R
option may be helpful to you. This makes the changes recursive, meaning that you'll not only make the changes to the directory but all files and directories underneath it in one shot:
chmod 770 -R mydir
While using -R
with chmod
can save you some time, it can also cause trouble if you have a mix of directories and files underneath the directory you're changing permissions on. The previous example gives permissions 770
to mydir
and all of its contents. If there are files inside, they are now given executable permissions to the user and group, since 7
includes the execute bit (value of 1
). This may not be what you want. We can use the find
command to differentiate these. While find
is out of the scope of this chapter, it should be relatively simple to see what the following commands are doing and how they may be useful:
find /path/to/dir/ -type f -exec chmod 644 {} \;
find /path/to/dir/ -type d -exec chmod 755 {} \;
Basically, in the first example, the find
command is locating all files (-type f
) in /path/to/dir/
and everything it finds, it executes chmod 644
against. The second example is locating all directories in this same path and changing them all to permission 755
. The find
command isn't covered in detail here because it easily deserves a chapter of its own, but I'm including it here because hopefully these examples are useful and will be handy for you to include in your own list of useful commands.
Changing the ownership of objects
Finally, we'll need to know how to change the ownership of files and directories. It's often the case that a particular user needs to gain access to an object, or perhaps we need to change the owning group as well. We can change user and group ownership of a file or directory with the chown
command. As an example, if we wanted to change the owner of a file to sue
, we could do the following:
sudo chown sue myfile.txt
In the case of a directory, we can also use the -R
flag to change the ownership of the directory itself, as well as all the files and directories it may contain:
sudo chown -R sue mydir
If we would like to change the group assignment to the object, we would follow the following syntax:
sudo chown sue:sales myfile.txt
Notice the colon separating the user and the group. With that command, we established that we would like the sue
user and the sales
group to own this resource. Again, we could use -R
if the object were a directory and we wanted to make the changes recursive.
Another command worth knowing is the chgrp
command, which allows you to directly change the group ownership of a file. To use it, you can execute the chgrp
command along with the group you'd like to own the file, followed by the username. For example, our previous chown
command can be simplified to the following, since we were only modifying the group assignment of that file:
# sudo chgrp sales myfile.txt
Just like the chown
command, we can use the -R
option with chgrp
to make our changes recursively, in the case of a directory.
Well, there you have it. You should now be able to manage permissions of the files and directories on your server. If you haven't worked through permissions on a Linux system before, it may take a few tries before you get the hang of it. The best thing for you to do is to practice. Create some files and directories (as well as users) and manage their permissions. Try to remove a user's access to a resource and then try to access that resource as that user anyway and see what errors you get. Fix those errors and work through more examples. With practice, you should be able to get a handle on this very quickly.