Part IV - Managing Systems
Users and Groups
Unix-like systems have a built-in understanding of users. Originally, these were intended to describe individual people interacting with the system through remote terminals (see Chapter 4 - A Brief History of Unix). That's still the case today, but user accounts are also used for many other purposes. A typical Unix-like system will have many "system users" that no one ever logs in to and that don't even have a "home" directory.
"to do list" by Marco Verch is Licensed under CC BY 2.0
In general, you can think of a user as a set of rules about what may and may not be done in the system. When a human being logs in to that user account, they will be bound by those rules. Alternatively, an automated task (perhaps repeated on some regular interval) could be assigned to such a set of rules.
On a Unix-like system, every process has an associated user which is known as
its owner. As the process interacts with the system (reading files,
creating new processes, etc.), the system allows or denies each request
according to the process's owner. For instance, if the process's owner has
permission to open the file at /etc/shadow
, then the process does, too.
"Running as"
It's common to speak of this relationship by saying that a process "runs as" a user. These are all statements you might find written in technical documentation:
- "nginx is running as the 'www-data' user."
- "She logged in as 'sally' but ran 'find' as 'mark.'"
- "Don't run untrusted scripts as 'root!'"
Whenever someone states that a process "runs as" a certain user, they're saying that the user is the owner of that process.
Groups
A group is a collection of users.
To understand how groups can be useful, consider how me might keep track of all the users who are allowed to administer the system's printers. Assume that that responsibility includes three separate tasks: adding new printers, configuring existing printers, and removing unwanted printers.
We could handle this without using groups. If a person named George was the only user that needed to perform this duty, then we could grant his user account permission to perform each task. If more people joined George, then we'd have to carefully assign each of those three permissions. If anyone took a new job, we'd need to remove the printer permissions without changing any others.
This would all be easier if we created a group called "printer-admin". We could configure that group to have the three printer-related privileges. Then, whenever a new administrator joined, we would add their account to the "printer-admin" group. Likewise, when they quit, we'd only remove them from that group.
In short, groups help maintain logical collections of rights for many users.
groups
Print the groups a user is in
vm$ groups
sally adm cdrom sudo dip plugdev lpadmin sambashare
vm$
To see a list of the groups that the current user account belongs to, run the
groups
command.
File ownership
vm$ ls /home/larry
ls: cannot open directory /home/larry: Permission denied
vm$ ls -o /home
total 102
drwx------ 72 larry 24576 Jul 01 10:55 larry
drwx------ 72 nancy 8374 Jul 09 10:55 nancy
drwx------ 72 sally 39827 Jul 14 10:55 sally
drwx------ 72 xavier 33432 Jul 11 10:55 xavier
vm$
We saw in Chapter 8 - All about sudo
that different directories may "belong" to different
users. A file's owner is a fundamental trait, just like its name. We can use
the ls
utility's -o
flag to see files and directories listed with their
owners.
In this example, each directory's owner is displayed in the third column from
the left. The directory's name is displayed in the final column. For
subdirectories of /home/
, the name and owner are often identical: Sally owns
the directory named sally
, and Larry owns the directory named larry
. That
sounds logical enough, but it doesn't have to be that way.
vm$ ls -l /usr/bin/mail-lock /usr/bin/ssh-agent
-rwxr-sr-x 3 root mail 14592 Dec 3 2012 /usr/bin/mail-lock
-rwxr-sr-x 1 root ssh 288880 Jan 18 2018 /usr/bin/ssh-agent
vm$
Programs stored in the /usr/bin
directory have more interesting access
controls. We'll use the ls
utility's -l
flag to view owner and group
membership.
The ssh-agent
executable file belongs to the "root" user, but the name of its
group is ssh
. And though the mail-lock
executable also belongs to the
"def. of parameters for root" user, its group is mail
.
chown
Change file owner and group
vm$ cat README.txt
cat: README.txt: Permission denied
vm$ ls -o
total 4
-r-xr----- 1 root 29 Nov 17 17:23 README.txt
vm$ sudo chown sally README.txt
vm$ ls -o
total 4
-r-xr----- 1 sally 29 Nov 17 17:23 README.txt
vm$ cat README.txt
Hello! I am a "readme" file.
vm$
You can use chown
to change files' owner.
You'll often need to use the sudo
utility because reassigning ownership is a
privileged operation. (See Chapter 8 - All about sudo
for more information.)
vm$ cat index.html
cat: index.html: Permission denied
vm$ ls -g
total 4
-rw-rw---- 1 root 67 Nov 17 17:51 index.html
vm$ sudo chown :sally index.html
vm$ ls -g
total 4
-rw-rw---- 1 sally 67 Nov 17 17:51 index.html
vm$ cat index.html
<!DOCTYPE html><html><body>Hello! I am an HTML file.</body></html>
vm$
You can also use chown
to change a file's group. Just write the group name
after a color (:
) character.
File Modes, revisited
vm$ echo 'echo Hello!' > greet.sh
vm$ ./greet.sh
-bash: ./greet.sh: Permission denied
vm$ chmod +x greet.sh
vm$ ./greet.sh
Hello!
vm$
In Chapter 13 - Scripting, we learned about how a file's "mode" determines whether it is executable or not.
vm$ chmod -x greet.sh
vm$ ./greet.sh
-bash: ./greet.sh: Permission denied
vm$ chmod -w greet.sh
vm$ echo > "# I can't write to the file anymore" >> greet.sh
-bash: greet.sh: Permission denied
vm$ chmod -r greet.sh
vm$ cat greet.sh
cat: greet.sh: Permission denied
vm$
There are two additional kinds of file permissions: readable and writable. If a file isn't readable by a given user, then that users won't be able to see its contents. If a file isn't writable by a given user, then that user won't be able to change its contents.
When we create a file, the system automatically grants our user account
permission to read and write that file. We can remove those positions if we
want, and we can even use the familiar chmod
utility to do it. We replace the
plus sign (+
) with the minus sign (-
) to remove.
vm$ chmod +r greet.sh
vm$ chmod +x greet.sh
vm$ ls -l greet.sh
-r-xr-xr-x 1 sally sally 68 Nov 22 18:21 greet.sh
vm$
When run with the -l
flag, the ls
utility also displays file mode
information. The first column of output contains a field of dashes and letters.
The second, third, and fourth character of the sequence describe the read,
write, and execute permissions for the file's owner, respectively.
If the second character is an r
, then the file's owner has the "read"
permission. If it is a dash (-
), then the owner does not. Likewise, the third
character is either a w
(signifying that the file is writable by its owner)
or a dash (signifying that it is not writable). The fourth character may either
be an x
(if the file is executable by its owner) or a dash (if it is not).
vm$ cat ./file-permission-field.txt
(r)ead, (w)rite, and e(x)ecute permissions for the file's owner
^
/ \
| | (r)ead, (w)rite, and e(x)ecute permissions for members of the file's group
| | ^
| |/ \
| || | (r)ead, (w)rite, and e(x)ecute permissions for all other users
| || | ^
| || |/ \
| || || |
-rwxrwxrwx
vm$
If that wasn't complicated enough, these same three permissions are also
maintained for the file's group and for all other users. The next six
characters in the output of ls
use the same pattern to communicate whether
the read, write, and execute permissions have been granted to each of those
two sets of users.
In the earlier example about printer administration, all members of the
printer-amdin
group were allowed to maintain the system's printers. This is
possible for files (for example, a file containing the list of active printers)
because the system controls "group" permissions separately from "owner"
permissions and "other user" permissions.
vm$ chmod -r greet.sh
vm$ chmod -w greet.sh
vm$ chmod -x greet.sh
vm$ ls -l greet.sh
---------- 1 sally sally 68 Nov 22 18:21 greet.sh
vm$ chmod u+rx greet.sh
vm$ chmod g+w greet.sh
vm$ chmod o+x greet.sh
vm$ ls -l greet.sh
-r-x-w---x 1 sally sally 68 Nov 22 18:21 greet.sh
vm$
If we want to modify those other permissions, we can once again use the chmod
utility. Now, we'll make our mode change even more specific so that it only
effects the permissions for the file's owner, its group, or all other users.
This is all done by prefixing the permissions list with another character.
We can add or remove permissions for the file's owner by prefixing the
permission list with a u
. We can add or remove permissions for the file's
group by prefixing the permission list with a g
. Finally, we can add or
remove permissions for all other users by prefixing the permission list with an
o
.
In Review
- Users are the way Unix-like systems express and enforce permissions for all interactions
- Groups are a convenient way to maintain permissions between many users
- Every file in the system designates one user account as its "owner", and it likewise "belongs" to one specific group
- Every file in the system has a "mode" which describes whether users can read, write, and execute it. That set is defined independently for a file's owner, for member of a file's group, and for all other users on the system.
- The
chmod
utility can be used to modify file permissions, and thels
utility can be used to review file permissions
Exercise
- Create a file named
announcements.txt
that only the root user can modify but that everyone can read. - Create a file named
penguins.sh
that only members of the group namedsudo
can delete.
Solution
-
You can create a file however you like. Here, we'll use output redirection (discussed in Chapter 11 - Process Boundaries):
vm$ echo Hello > announcements.txt
Next, we'll remove "write" permissions for the file's group:
vm$ chmod g-w announcements.txt
And also remove "write" permissions for everyone else:
vm$ chmod o-w announcements.txt
Since we want to control access for one specific user, we'll have to make that user the owner:
vm$ chown root announcements.txt
That's it! We can verify using the
ls
utility or by trying to read to and write from the file as a non-root user.vm$ ls -l announcements.txt -rw-r--r-- 1 root sally 6 Nov 24 18:08 announcements.txt
This is telling us that the owner is allowed to read and write (
rw-
), that the group is only allowed to read (r--
), and that all other users are only allowed to read (again,r--
). It also shows that the file's owner is theroot
user.We can also verify experimentally by trying to read the file as a non-root user (which should work) and by trying to write to the file as a non-root user (which should not work):
vm$ cat announcements.txt Hello vm$ echo 'Another line of text' >> announcements.txt -bash: announcements.txt: Permission denied
-
We'll make the file with output redirection again:
vm$ echo true > penguins.sh
There is no file permission that allows/disallows deleting specifically; any user with "write" permission to a file may also delete that file. There's a good reason for this: any user who can edit a file is able to remove all of that file's contents. In other words, they can essentially delete the file. So there's not much use in defining a separate "delete" permissions. Permissions are already complicated enough!
That means we can rewrite this exercise to say, "Create a file that only members of the group named
sudo
can modify." If we want to grant access to a file for a specific group, that file needs to "below" to the group. Setting file ownership is a job forchown
:vm$ chown :sudo penguins.sh
We can verify using
ls
:vm$ ls -l penguins.sh -rw-r--r-- 1 sally sudo 5 Dec 8 17:42 penguins.sh
The word
sudo
in the fourth column proves that the file now belongs to the group namedsudo
.We use the
chmod
utility to set the permissions for files. In this case, we want to target the file's group (so we'll useg
), we want to add a permission (so we'll use the plus sign,+
), and we want the select the "write" permission (so we'll usew
):vm$ chmod g+w penguins.sh
Once again,
ls
will let us review the permission information:vm$ ls -l penguins.sh -rw-rw-r-- 1 sally sudo 5 Dec 8 17:42 penguins.sh
That's almost right, but the instructions say that only members of the
sudo
group should be able to delete the file. The permissions field reads-rw-rw-r--
. The firstrw-
means that the owner is also allowed to modify (and therefore delete) the file. We'll need to usechmod
to revoke that permission:u
to target the file's owner,-
to remove the permission, andw
to select the "write" permission:vm$ chmod u-w penguins.sh
Now (finally), we should have a file in the desired state.
vm$ ls -l penguins.sh -r--rw-r-- 1 sally sudo 5 Dec 8 17:42 penguins.sh