Users and Permissions

Building off the previous post, we now explore the dual topics of users and permissions.

Multiple Users

Linux is inherently a multi-user operating system. This can be quite confusing for desktop users of Windows or MacOS, and completely foreign to smartphone/table users.

Using Windows as an example, it’s common for someone to have a username that matches their real name. Once they open the computer and type their password, that’s about as far as they get. Often, the default user in Windows is an Administrator, so they are unrestricted and never consider rights and privileges associated with their day-to-day work.

Linux and other UNIX-like operating systems have the central concept of a user. There are effectively unlimited users available on a Linux system. Similarly, Linux has the concept of a group, which can contain one or more users. A group cannot be a member of another group, but a user can be a member of many groups. Fairly intuitive.

Linux keeps track of these users by means of a uid, short for “user id”. Similarly, it keeps track of groups by a gid short for “group id”. These are simple integers that are unique to each user and group.

To see this in action, open a Terminal and type the following:

devil@ubuntuVM:~$ id
uid=1000(devil) gid=1000(devil) groups=1000(devil),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare)

The id command will display the uid and gid of the active user, as well as the groups that user is a part of, plus their gid.

You’ll notice some familiar looking words in there. The first result uid=1000(devil) simply tells me that I am user id 1000, and my username is devil. Similarly, I have a group named devil, and its gid is 1000. Ubuntu assigns new users their own dedicated group, so you’ll often see this.

Did you notice the 27(sudo) entry? Here is our first exposure to permissions. The default configuration of sudo(we learned this in the last lesson) will only allow users in the sudo group to run commands with superuser privilege.

The other groups listed here perform a similar function, allowing any user in that group to perform some privileged function.

Since users and groups are effectively unlimited, you can craft the permissions to satisfy access concerns for nearly any random arrangement of people.

File Permissions

In the previous lesson, you may have noticed a bunch of extra text in columns to the left of the directory listing. I ignored that on purpose, but I will explain it now.

Let’s use a single example to keep it simple:

root@ubuntuVM:/# ls -l /home
total 4
drwxr-xr-x 15 devil devil 4096 Jun 17 22:51 devil

This output tells me that within the /home directory, there is a sub-directory called devil. The full path to this directory is /home/devil.

The first column basically looks like nonsense, but it has a meaning. It reads drwxr-xr-x, which is a graphical representation of its permissions.

In Linux, a file or directory has three sets of permissions for three sets of users. The permissions are read, write, and execute. They are often abbreviated as r, w, and x. You’ll notice that the devil directory starts with drwx, which simply means that devil is a directory (d) with the read, write, and execute permissions set (rwx) on the first set of users.

read and write are fairly obvious. What is execute? In the case of a script, it will not run when called directly unless the execute permission is enabled. A directory will not display its contents unless its execute permission is set. Think of execute as a permission that allows you to “do stuff” with it.

What are the sets of users? They are as follows:

  • user
  • group
  • other

When you list a file permission using ls -l, it will display the permissions in a string in the order above. Set permissions are displayed with r, w, and x. If a permission is unset, it will display -.

Going back to my example above, we can interpret the permissions for /home/devil as

  • user = read, write, execute
  • group = read, execute
  • other = read, execute

OK, seems good enough. Who are user and group? They are displayed in the next column. In this case, /home/devil is owned by user=devil and group=devil. All non-devil users and non-devil groups are given the permissions defined in other.

Linux allows you to change a file’s permissions at any time using the chmod command. chmod accepts two forms for permissions. One is intuitive, one a bit less so.

The intuitive form users the familiar abbreviations from before. Let’s create a new file using touch, then modify its permissions. What do you think this does?

devil@ubuntuVM:~$ touch testfile
devil@ubuntuVM:~$ chmod u=rwx,g=rw,o=r testfile

If you said “read-write-execute for the user, read-write for the group, read-only for all others” then you’re getting it!

If not, just take another look until it clicks.

The unintuitive form of chmod is known as “numeric mode”, using numbers to represent permissions instead of letter abbreviations. Linux nerds love to use powers of 2, and they have done so here.

Consider the following value-number pairs:

  • read = (2^2) = 4
  • write = (2^1) = 2
  • execute = (2^0) = 1

The neat thing about powers of two is that each pair or triplet adds to a unique value. Using these powers of two, we can express up to 8 combinations (2^3) of permissions with just an integer.

  • 0 (no permissions)
  • 1 (execute)
  • 2 (write)
  • 3 (write-execute) = 2 (write) + 1 (execute)
  • 4 (read)
  • 5 (read-execute) = 5 (read) + 1 (execute)
  • 6 (read-write) = 4 (read) + 2 (write)
  • 7 (read-write-execute) = 4 (read) + 2 (write) + 1 (execute)

Not obviously useful, but consider this example. Instead of writing out the long form chmod u=rwx,g=rwx,o=rx, I could simply write chmod 775.

Take a look at the u=rwx and think about how that is equivalent to 7 using the numeric math above.

File Ownership

OK, now we know how to create a file (touch) and modify its permissions (chmod). How do we change ownership? We use chown.

Let’s create a file, change its permission, then change its ownership.

root@ubuntuVM:~# touch test
root@ubuntuVM:~# ls -l test
-rw-r--r-- 1 root root 0 Jun 17 23:24 test
root@ubuntuVM:~# chmod 664 test
root@ubuntuVM:~# ls -l test
-rw-rw-r-- 1 root root 0 Jun 17 23:24 test
root@ubuntuVM:~# chown devil:root test
root@ubuntuVM:~# ls -l test
-rw-rw-r-- 1 devil root 0 Jun 17 23:24 test

A Few Housekeeping Commands

Since we’re working with files already, let’s learn how to move, copy, rename, and delete.

root@ubuntuVM:~# cp test test2
root@ubuntuVM:~# ls -l
total 4
-rw-rw-r-- 1 devil root    0 Jun 17 23:24 test
-rw-r--r-- 1 root  root    0 Jun 17 23:27 test2

Notice that test2 is created with different permissions from test? All new files will be created with owner and group equal to the current user. In this case, root.

Now let’s rename test2 to test69 (lol) using mv.

root@ubuntuVM:~# mv test2 test69
root@ubuntuVM:~# ls -l
total 4
-rw-rw-r-- 1 devil root    0 Jun 17 23:24 test
-rw-r--r-- 1 root  root    0 Jun 17 23:27 test69

Then finally, we clean up after ourselves by removing the files with rm.

root@ubuntuVM:~# rm test test69
root@ubuntuVM:~# ls -l
total 0

Next Steps

In the next lesson, I will cover how to start, stop, enable and disable services. A service is a program that executes in the background without user interaction. This is particularly useful for running servers and automatic tasks like updates, backups, and cleanup.


Tip Jar

If you're getting value from my writing, please support my efforts with a donation. You can donate directly using my public Ethereum address bowtieddevil.eth. Or you can use the donation button below, which works through my self-hosted BTCPay Server.

See also