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:
- User name
- User id (UID)
- Primary group id (GID)
- Home directory
- Shell
- Possibly real name and contact info
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:
- Username
- Hashed password. This field itself is broken into 4 fields separated with
$characters:- The hash algorithm.
yindicates 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. - Parameters for the hash algorithm.
- 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.
- The hashed value of the user's salt + password.
- The hash algorithm.
- Day of last password change. This is the number of days since the Unix epoch which is January 1, 1970.
- 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.
- Maximum days before change. 99999 essentially means they never need to change their password (that is 274 years).
- Warning period, which is the amount of time the user is warned that their password will need to be changed.
- The inactive period, which is the number of days after password expiration before the account is disabled. If empty, there is no limit.
- 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.
- 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.