Users and Permissions

 

Overview

Today we will look at the tools Linux has for managing users and groups, and seeing and changing permissions on files. This forms the backbone of Linux system security.


 

Creating and Removing Users

Users can be created with the adduser command. To add a new user called "bsmith", we could use the following command:

$ sudo adduser bsmith

The system will ask for the new user's password, and then optional information for the user:

$ sudo adduser bsmith
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for bsmith
Enter the new value, or press ENTER for the default
        Full Name []: Bob
        Room Number []: Smith
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] y

Like always, passwords are not echoed back to you when you type them in. Should you wish to change the password of a user at a later date, that can be done with the passwd command. A user can change their own password just by running the command with not arguments:

$ passwd

But will need to enter their existing password first. With sudo we can change the password for any user, without needing to know existing passwords:

$ sudo passwd bsmith

Each user has a home directory, which by default is in /home/. So the user bsmith would have /home/bsmith created as part of the adduser command. We can set a different home directory:

$ sudo adduser bsmith --home /home/people/bobby

We can also change their shell (the default is bash), and primary group, should we wish to.

When a user is created, they receive a home directory and also some initial files in their home directory. The files they start with come from /etc/skel. On most systems, these "skeleton" files are just a few bash startup files. However if you want users to start with specific files or settings, this is how that can be done.

Users can be removed with the userdel command:

$ sudo userdel bsmith

This must be done as root of course. It does not remove the user's home directory which can be done separately.


 

User Details

User information is primarily stored in the file /etc/passwd which, confusingly enough, does not store password information (though it used to). It does keep the following information:

This file is readable by all users on a system. It is used by many programs to map UID's to user names (for instance if ls or ps need to list users). The UID is used internally to keep track of ownership of files. A file will not store the user name of its owner, but rather the UID.

As you can see if you look in /etc/passwd, there are many other users which exist beyond just root and your personal user. Certain systems create a user account which owns the files and runs the processes for that system. For example the mail user owns mailbox files and runs the process to check mail. These users have nologin listed for their shell, indicating they are not meant to be logged in as for normal use.


 

Passwords

Passwords are no longer stored in the /etc/passwd file, but instead the /etc/shadow file, which is not world-readable. Each user has a line in this file storing their password. For instance, the user bsmith, might have a line like the following:

bsmith:$y$j9T$rVPowkg0GHE.LSqEFdVeb/$1XI2wBuvpAzgsLXSXFjjgueH5F9E2fswdBEuhZuXH40:20485:0:99999:7:::

The fields in this line are separated with : characters. The fields are:

  1. Username
  2. Hashed password. This field itself is broken into 4 fields separated with $ characters:
    1. The hash algorithm. y indicates yescrypt, a modern hash algorithm. Others include the MD5, blowfish, and SHA. Passwords are never stored in plain text, but hashed. This way even if someone sees the shadow file, they will not know your password.
    2. Parameters for the hash algorithm.
    3. The salt. Salt is a random string that is created when the password is set. When a user's password is hashed, we first append it to the salt. The purpose of this is to make the hashed values different for users even if they have the same passwords. For instance, the password used for the above is "abcdef". But if we make a new user with the same password, they will get a different salt and thus have a different hashed value. This is to make rainbow table attacks infeasible. Without salt, we could compute the hashes for a bunch of common passwords and see if they match anything in the file. But with salt that is not possible.
    4. The hashed value of the user's salt + password.
  3. Day of last password change. This is the number of days since the Unix epoch which is January 1, 1970.
  4. Minimum days before change. This is 0 in this case, which means the user can change their password now. If it were 7, for instance, they would need to wait a week between changes.
  5. Maximum days before change. 99999 essentially means they never need to change their password (that is 274 years).
  6. Warning period, which is the amount of time the user is warned that their password will need to be changed.
  7. The inactive period, which is the number of days after password expiration before the account is disabled. If empty, there is no limit.
  8. The account expiration date. If present, this will be the number of days since the epoch at which the account will be disabled. Used for temporary accounts.
  9. A reserved field for possible use in the future.

The password itself is stored nowhere on the system. When a user enters it, we add it to the salt, then hash it. That hashed value is then checked against the hash in the system. If they match, the password must have been the same.

The fields for password expiration should not be edited manually, but rather managed with the chage command. For instance, we can set the maximum password age with the following:

# chage -M 30 bsmith

The man page details how the other fields can be modified.


 

Locking the root account

On most Linux systems, the root account is locked by default, meaning one cannot login to that account with a password. One can only become root by logging in as another user, then using sudo. The benefit of this is that attackers cannot get root access by simply guessing a root password. They must also guess the username of a user with sudo. If you look in the /var/log/auth.log file, you will see many failed login attempts for the root user for any machine that is publicly addressable on the internet.

The /etc/shadow file indicates that a password is locked by having a * for the password field. There is no hash algorithm, salt, or hashed password. Any attempts to login as a user with that password field simply fail.

You can lock the password for root, or any other account, by passing the -l flag to passwd:

$ sudo passwd -l root

 

Groups

Groups are used by Linux to offer more fine-grained access control. The user permissions can affect only the owner, and the "other" permissions affect ever user. But with groups, we can give access to files to a selected group of users.

Each file has one user and one group listed as the owner, which the user and group permissions apply to. So anyone in the matching group for a file has the group permissions applied to them for that file.

Every user has one primary group. By default on most systems, every user gets a group with the same name as their username, which serves as their primary group. The primary group can be set when creating a user with adduser. Your primary group is indicated in the /etc/passwd file.

Your primary group is the one which files you create will have as their group. So if your primary group is "webteam", then any files you create will have "webteam" as the group. This makes it easy for a set of users to share access to files and directories.

You can see which groups you are a part of with the groups command:

$ groups
ifinlay sudo lpadmin

Here, my primary group is "ifinlay". I am also in the sudo group which are those users authorized to run commands as sudo (we can also add specific users to /etc/sudoers), and the lpadmin group which are those users allowed to manage printers.

We can add a user to a group with the usermod command:

$ sudo usermod -aG lpadmin bsmith

Group information is stored in /etc/group which is world-readable. This lists the name of each group, the group id, and the users belonging to it.


 

File Permissions

File permissions are covered in CPSC 225, but you may need a refresher. If so, you can look at File Permissions through the end of that page.


 

Default Permissions

When making a new file, how does Linux decide what permissions it should get by default? That is controlled by the umask utility. The way in which umask functions is not exactly intuitive; rather than set the default permissions, we set a mask which is a modification to a default.

We can see the current umask by running the following command:

$ umask
0002

The initial 0 is a "special" bit we will ignore for now, and will never be set. So the effective umask here is 002.

When a new file or directory is created, they start with the initial permissions of 666 rw-rw-rw for files and 777 rwxrwxrwx for directories. We then apply the umask by removing the permissions set there.

For files this would be:

  666
- 002
  ---
  664  rw-rw-r--

And for directories:

  777
- 002
  ---
  775  rwxrw-r-x

The umask essentially tells us which permissions we want to remove, with the value of 002 removing "other" write permission. If we want to also remove "group" write permission, we could set our umask to 022 instead, which is a common value. That could be done like this:

$ umask 022

Now all new files will have this mask removed from their initial permissions, so files will be 644 and directories 755 by default.

The umask is a property of a process, and is inherited by children processes. Setting it like this only affects the current shell. If we want to always use a certain umask, it should be set in the .bash_profile or similar startup file.


 

Changing Ownership

Only root is allowed to change the ownership of files. It's important regular users can neither "take" files from others or "gift" files to them. If we have root access, we can use the chown command to change ownership. The first argument is the new owner of the file, and the second is the file(s) to be changed. For instance we can change the ownership of a file to bsmith with the following:

$ sudo chown bsmith /tmp/file1

We can also change the group of a file using this as well:

$ sudo chown bsmith:developers /tmp/file1

Or we can change only the group:

$ sudo chown :developers /tmp/file1

Changing ownership is sometimes needed, for example files in /var/www/html should typically be owned by the "www-data" user. Also, when moving files from one Linux system to another, you may need to change ownership of user files, if users on the new system have different UIDs.


 

Changing Users

We can change the user we are logged in as using either the sudo command, or the su command. With the former, we can execute a command as if we were the root user:

$ sudo whoami
root
$ sudo apt install gdb

We can also get a root shell with the the -i flag:

$ sudo -i
# whoami
root

We can also use the su command to switch to any user. For instance, the following will allow us to switch to the user "bsmith":

$ su - bsmith

If we are running as a regular user, this will prompt us to enter the password for bsmith. If the password is correct, we will then switch to that user. Otherwise the command fails.

If we run this as root, we can login as any user without needing a password:

$ sudo su - bsmith

The - in the su commands above makes the login complete, by running the user (bsmith in this case) shell startup files, and switching to their home directory. This is generally preferred when logging in as another user. Without the - we simply switch user id's, but don't initialize anything else.