Chapter 13
Managing Users and Groups

At the core of Linux security is the user account. Each individual who accesses a Linux system should have a unique account assigned to them. Adding, modifying, and deleting user account authorizations are some of the most basic, but important, tasks you do to protect your system. Access granted to user accounts are more easily managed by putting the various accounts into groups. Managing these groups of users and defining what they are allowed to access also provides base‐level protection.

In addition to these user accounts and groups, it is important to understand basic Linux file and directory permissions, including how to view them and interpret their meanings. The codes used to set and modify permissions can be a little cryptic, and without full understanding, you risk leaving files or directories opened to unauthorized access.

Our goal in this chapter is to provide a basic understanding of managing user accounts and groups as well as file and directory permissions. We'll provide guidance that will help you avoid basic security problems, while increasing your system's usability for authorized users.

Understanding Linux Permissions

The core security feature of Linux is file and directory permissions. Linux accomplishes this by assigning each file and directory an owner and allowing that owner to set the basic security settings to control access to the file or directory. This section walks through how Linux handles ownership of files and directories, as well as the basic permissions settings that you can assign to any file or directory on your Linux system.

You can view permission settings for a specified file by adding the ‐l option to the ls command. To see these settings on a directory, add the ‐d option to the ‐l option.

$ history > keepHistory.txt
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 sysadmin sysadmin 12933 Jan 19 19:14 keepHistory.txt
$
$ ls ‐ld /etc/
drwxr-xr-x 94 root root 4096 Dec 12 15:50 /etc/
$

Figure 13.1 shows a chart that provides names for all of the various information displayed using the ls ‐l command. You'll want to refer to this graphic as you progress through this chapter section.

Snapshot of file information chart

FIGURE 13.1 File information chart

Understanding Ownership

The owner and group information of a file (or directory) is important, because Linux uses this information in a three‐tiered approach for protecting files and directories.

  • Owner—Within the Linux system, each file and directory is assigned to a single user account. Permissions set in this tier apply only to the file's owner. Because the owner is a user account name, this tier is also called the user category.
  • Group—The Linux system also assigns each file and directory to a single group of users. The administrator can then assign that group specific privileges to the file or directory that differ from the owner privileges.
  • World—This permission category is assigned to any user account that is not the owner nor in the assigned group. Permissions set in this level are often sparse due to the wide range of accounts to which they apply. This tier is also called others, because it applies to those who are neither the file's owner or in its group.

Many Linux distributions (such as Ubuntu and Red Hat) assign each user account to a separate group with the same name as the user account. This helps prevent accidental sharing of files. However, this can also make things a little confusing when you're working with owner and group permissions and you see the same name appear in both areas. Here is an example where the owner and group names differ—the owner is root, and the group is shadow :

$ ls ‐l /etc/shadow
-rw-r----- 1 root shadow 1027 Dec 4 20:13 /etc/shadow
$

When a user creates a file or directory, by default the Linux system automatically assigns that user as the owner and uses the primary group (discussed later in this chapter) the user belongs to as the group for the file or directory. You can change the default owner and group assigned to files and directories using Linux commands. The following sections show how to do that.

CHANGING FILE OR DIRECTORY OWNERSHIP

The root user or an account with super user privileges can change the owner assigned to a file or directory by using the chown command. This command's format looks like this:

chown [OPTIONS] NEWOWNER FILENAMES

The NEWOWNER parameter is the username of the new owner to assign to the file or directory, and FILENAMES is the name of the file or directory to change.

$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 sysadmin sysadmin 12933 Jan 19 19:14 keepHistory.txt
$
$ sudo chown root keepHistory.txt
[sudo] password for sysadmin:
$
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root sysadmin 12933 Jan 19 19:14 keepHistory.txt
$

If needed, you can specify more than one file or directory by placing a space between each file or directory name. There are a few command‐line options available for the chown command, but many are not used much. One that may be helpful for you is the ‐R option, which recursively changes the owner of all files under the specified directory.

CHANGING THE FILE OR DIRECTORY GROUP

The file or directory owner, or an account with super user privileges, can change the group assigned to the file or directory by using the chgrp command. This command's syntax format is as follows:

chgrp [OPTIONS] NEWOWNER FILENAMES

The NEWGROUP parameter is the name of the new user group assigned to the file or directory, and the FILENAMES parameter is the name of the file or directory to change. If you're the owner of the file, you can only change the group to one that you belong to. The root user, or an account with super user privileges, can change the group to any group on the system.

$ whoami
sysadmin
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root sysadmin 12933 Jan 19 19:14 keepHistory.txt
$
$ sudo chgrp users keepHistory.txt
[sudo] password for sysadmin:
$
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root users 12933 Jan 19 19:14 keepHistory.txt
$

The chgrp command also uses the ‐R option to recursively change the group assigned to all files and directories under the specified directory.

Besides changing a file's group with chgrp, you can also change it with the chown command. Just put a colon (:) in the front of the new group name.

$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root users 12933 Jan 19 19:14 keepHistory.txt
$
$ sudo chown :games keepHistory.txt
$
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root games 12933 Jan 19 19:14 keepHistory.txt

Even more convenient is the ability to change the file's owner and group at the same time with the chown command. Put the new owner first, followed by a colon, and end with the new group.

$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root games 12933 Jan 19 19:14 keepHistory.txt
$
$ sudo chown root:sysadmin keepHistory.txt
$
$ ls ‐l keepHistory.txt
-rw-rw-r-- 1 root sysadmin 12933 Jan 19 19:14 keepHistory.txt
$

Keep in mind that you still have to use the root account or an account with super user privileges to perform these chown command changes to files.

Controlling Access Permissions

Once you've established the file or directory owner and group, you can assign specific permissions to each. Linux uses three types of permission controls on files and directories.

  • Read—The ability to access the data stored within the file or display a directory's contents
  • Write—The ability to modify the data stored within the file or create, rename, modify attributes of, and delete files within a directory
  • Execute—The ability to run the file on the system, or the ability for a user to change their working directory to this directory (if also set on all parent directories)

You can assign each tier of protection (owner, group, and world) different read, write, and execute permissions. This creates a set of nine different permissions that are assigned to each file and directory on the Linux system. These permissions appear in the ls output after the file type code when you use the ‐l option (shown previously in Figure 13.1). The r stands for read, w for write, and x for execute.

Figure 13.2 shows an example of file and directory permission data with the owner, group, and world tiers identified.

Snapshot of permissions with tier identification

FIGURE 13.2 Permissions with tier identification

The order of the permissions within each tier is important. It is always in rwx order, and if a dash () is shown in one of the permission's place, that means that particular permission is not granted.

The root user account, an account with super user privileges, or the owner of the file or directory can change the assigned permissions. The command to change permissions is chmod. The chmod command can use two different modes for denoting the permission settings: symbolic mode and octal mode.

In symbolic mode, you denote permissions by using a letter code for the tier: user (u), group (g), others (o), or all (a). Notice that this mode refers to the owner tier as “user” and the world tier as “others,” so you have to pay attention when using this command!

With this mode, the permissions syntax code is fairly easy: read (r), write (w), or execute (x). The tier and permission codes are separated with a plus sign (+) if you want to add the permission, a minus sign () to remove the permission, or an equal sign (=) to set the permission as the only permission. Here is an example of using symbolic mode with the chmod command:

$ history > newHistory.txt
$ ls ‐l newHistory.txt
-rw-rw-r-- 1 sysadmin sysadmin 14296 Jan 21 16:06 newHistory.txt
$
$ chmod g‐w newHistory.txt
$
$ ls ‐l newHistory.txt
-rw-r--r-- 1 sysadmin sysadmin 14296 Jan 21 16:06 newHistory.txt
$ 

In this example, the g‐w code in the chmod command indicates to remove the write permission for the group tier from the newHistory.txt file.

Using symbolic mode, you can combine the letter codes for the various tiers and permissions both to make multiple changes in a single chmod command, as shown here:

$ chmod ug=rwx newHistory.txt
$ ls ‐l newHistory.txt
-rwxrwxr-- 1 sysadmin sysadmin 14296 Jan 21 16:06 newHistory.txt
$

The ug code assigns the change to both the owner and the group levels, while the rwx code assigns the read, write, and execute permissions. The equal sign indicates to set those permissions.

The second mode available in chmod is called octal mode. With octal mode, the nine permission bits are represented as three octal numbers, one each for the owner, group, and world permission tiers. Table 13.1 shows how the octal number matches the three symbolic mode permissions.

TABLE 13.1: Octal Mode Permissions

OCTAL VALUE PERMISSION MEANING
0 ‐‐‐ No permissions
1 ‐‐x Execute only
2 ‐w‐ Write only
3 ‐wx Write and execute
4 r‐‐ Read only
5 r‐x Read and execute
6 rw‐ Read and write
7 rwx Read, write, and execute

In octal mode syntax, there is a single digit placed in the location to represent the permissions for that tier: OwnerGroupWorld . So, the octal mode number 640 would set read and write (6) permissions in the owner tier, it would set only read (4) in the group level, and no permissions (0) would be granted in the world tier. Here is an example of using chmod with octal mode syntax:

$ ls ‐l newHistory.txt
-rwxrwxr-- 1 sysadmin sysadmin 14296 Jan 21 16:06 newHistory.txt
$
$ chmod 651 newHistory.txt
$
$ ls ‐l newHistory.txt
-rw-r-x--x 1 sysadmin sysadmin 14296 Jan 21 16:06 newHistory.txt
$

The 651 octal mode set the owner‐level permissions to read and write (6), the group permissions to read and execute (5), and the world level permission to execute only (1). This is a handy way to set all of the permissions for a file or directory in a single command.

Exploring Special Permissions

There are three special permission bits that Linux uses for controlling the advanced behavior of files and directories.

The Set User ID (SUID) bit is used with executable files. It tells the Linux kernel to run the program with the permissions of the file owner and not the user account actually running the file. This feature is most commonly used in server applications that must run as the root user account to have access to all files on the system, even if the user launching the process is a standard user.

The SUID bit is indicated by an s in place of the execute permission letter for the file owner: rwsr‐xr‐x. The execute permission is assumed for the system to run the file. If the SUID bit is set on a file that doesn't have execute permission for the owner, it's indicated by a capital S.

To set the SUID bit for a file, in symbolic mode add s to the owner permissions, or in octal mode include a 4 at the start of the octal mode setting.

# chmod u+s myapp
# chmod 4750 myapp

The Set Group ID (GUID) bit works differently in files and directories. For files, it tells Linux to run the program file with the file's group permissions. It's indicated by an s in the group execute position: rwxrwsr‐‐. Like SUID, the execute permission is assumed for the system to run the file, and if the SGID bit is set on a file without group tier execute permission, it's indicated by a capital S.

For directories, the GUID bit helps us create an environment where multiple users can share files. When a directory has the GUID bit set, any files that users create in the directory are assigned the group of the directory and not that of the user. That way, all users in that group can have the same permissions to all of the files in the shared directory.

To set the GUID bit, in symbolic mode add s to the group permissions, or in octal mode include a 2 at the start of the octal mode setting.

# chmod g+s /sales
# chmod 2660 /sales

Finally, the sticky bit is used to protect a file from being deleted by those who don't own the file, even if they belong to the group that has write permissions to the file. The sticky bit is denoted by a t in the execute bit position for others: rwxrw‐r‐t.

The sticky bit is often used on directories shared by groups. The group members have read and write access to the data files contained in the directory, but only the file owners can remove files from the shared directory.

To set the sticky bit, in symbolic mode add t to the world tier permissions, or in octal mode include a 1 at the start of the octal mode setting:

# chmod o+t /sales
# chmod 1777 /sales

Managing Default Permissions

When a user creates a new file or directory, the Linux system assigns it a default owner, group, and permissions. The default owner, as expected, is the user who created the file. The default group is the owner's primary group.

The user mask feature defines the default permissions that Linux assigns to the file or directory. The user mask is an octal value that represents the bits to be removed from the octal mode 666 permissions for files, or the octal mode 777 permissions for directories.

The user mask value is set with the umask command. You can view your current umask setting by simply entering the command by itself on the command line.

$ umask
0022
$

The output of the umask command shows four octal values. The first octal value represents the mask for the SUID (4), GUID (2), and sticky (1) bits assigned to files and directories you create. The next three octal values mask the owner, group, and world level permission settings.

The mask is a bitwise mask applied to the permission bits on the file or directory. Any bit that's set in the mask is removed from the permissions for the file or directory. If a bit isn't set, the mask doesn't change the setting. Table 13.2 demonstrates how the umask values work in practice when creating files and directories on your Linux system.

TABLE 13.2: Results from Common umask Values for Files and Directories

UMASK CREATED FILES CREATED DIRECTORIES
000 666 (rw‐rw‐rw‐) 777 (rwxrwxrwx)
002 664 (rw‐rw‐r‐‐) 775 (rwxrwxr‐x)
022 644 (rw‐r‐‐r‐‐) 755 (rwxr‐xr‐x)
027 640 (rw‐r‐‐‐‐‐) 750 (rwxr‐x‐‐‐)
077 600 (rw‐‐‐‐‐‐‐) 700 (rwx‐‐‐‐‐‐)
277 400 (r‐‐‐‐‐‐‐‐) 500 (r‐x‐‐‐‐‐‐)

You can test this by creating a new file and directory on your Linux system:

$ umask
0002
$
$ mkdir test1
$ ls ‐ld test1
drwxrwxr-x 2 sysadmin sysadmin 4096 Jan 21 16:35 test1
$
$ touch test2
$ ls ‐l test2
-rw-rw-r-- 1 sysadmin sysadmin 0 Jan 21 16:35 test2
$

The umask value of 0002 created the default file permissions of rw‐rw‐‐r‐‐, or octal 664, on the test2 file, and rwxrwxr‐x, or octal 775, on the test1 directory, as expected.

You can change the default umask setting for your user account by using the umask command from the command line.

$ umask 027
$ touch test3
$ ls ‐l test3
-rw-r----- 1 sysadmin sysadmin 0 Jan 21 16:40 test3
$

The default permissions for the new file have changed to match the umask setting. Note that you can use a three‐digit number for indicating a new user mask setting, if you do not want to subtract any of the special permissions.

The umask value is normally set in a script that the Linux system runs at login time, such as in the /etc/profile file. If you override the setting at the command line, that will apply only for the duration of your session. You can override the system default umask setting by adding it to an environment file in your home directory. Environment files are covered later in this chapter.

Using Access Control Lists

The basic Linux method of permissions has one drawback in that it's somewhat limited. You can only assign permissions for a file or directory to a single group and a user account. In a complex business environment with different groups of people needing different permissions to files and directories, that doesn't work.

Linux developers have devised a more advanced method of file and directory security called an access control list (ACL). The ACL allows you to specify a list of multiple users or groups and the permissions that are assigned to them. Like the basic security method, ACL permissions use the same read, write, and execute permission bits, but now can be assigned to multiple users and groups.

To employ the ACL feature in Linux, you use the setfacl and getfacl commands. With getfacl, you can view the ACLs assigned to a file or directory. If you've only assigned basic security permissions to the file, those still appear in the getfacl output.

$ touch testFile.txt
$ ls ‐l testFile.txt
-rw-rw-r--. 1 sysadmin sysadmin 0 Jan 21 13:11 testFile.txt
$
$ getfacl testFile.txt
# file: testFile.txt
# owner: sysadmin
# group: sysadmin
user::rw-
group::rw-
other::r--
 
$

To assign permissions for additional users or groups, you use the setfacl command.

setfacl [OPTIONS] RULE FILENAMES

The setfacl command allows you to modify the permissions assigned to a file or directory using the ‐m option or to remove specific permissions using the ‐x option. You define the RULE with three formats.

u[ser]:uid:perms
g[roup]:gid:perms
o[ther]::perms

To assign permissions for additional owner (user) accounts, use the user format; for additional groups, use the group format; and for world (other), use the other format. For the uid or gid values, either you can use the numerical user ID or group ID or you can use the names. The setfacl command in this example adds read and write permissions for the games group to the testFile.txt file.

$ setfacl ‐m g:games:rw testFile.txt
$ ls ‐l testFile.txt
-rw-rw-r--+ 1 sysadmin sysadmin 0 Jan 21 13:11 testFile.txt
$

Notice that there's no output from the setfacl command. When you list the file, only the standard owner, group, and world permissions are shown, but notice that there's a plus sign (+) added to the permissions list. This indicates that the file has additional ACLs applied to it. To view the additional ACLs, use the getfacl command.

$ getfacl testFile.txt
# file: testFile.txt
# owner: sysadmin
# group: sysadmin
user::rw-
group::rw-
group:games:rw-
mask::rw-
other::r--
 
$

The getfacl output now shows that there are permissions assigned to two groups. The default file group is assigned read and write permissions, and also the games group has read and write permissions to the file.

To remove the permissions, use the ‐x option along with the setfacl command.

$ setfacl ‐x g:games testFile.txt
$ getfacl testFile.txt
# file: testFile.txt
# owner: sysadmin
# group: sysadmin
user::rw-
group::rw-
mask::rw-
other::r--
 
$

Linux also allows you to set a default ACL on a directory that is automatically incorporated into any file created in the directory. This feature is called inheritance. To create a default ACL on a directory, you'll need to have super user privileges and start the rule with a d: followed by the normal rule definition. That looks like this:

$ sudo setfacl ‐m d:g:games:rw /games

This example assigns the read and write permissions to the games group for the /games directory. Now all files created in that directory will automatically be assigned read and write permissions for the games group.

File and directory permissions are only one layer of security in a Linux system. Another layer that is rather important involves user accounts. We'll look at that topic next.

Managing User Accounts

Adding, modifying, and deleting user account credentials—which includes usernames, account information, and passwords—is an important (but tedious) part of system administration. Managing user accounts and looking at the underlying configuration is covered in the following sections.

Adding Accounts

To add a new user account on the system, the useradd utility is typically used. On some distributions, such as Ubuntu, a script called adduser is used when adding users to the system, but it invokes the useradd program to handle the actual task.

The adding accounts process actually involves several players besides the core useradd program. Figure 13.3 depicts the process.

Snapshot of adding a user account

FIGURE 13.3 Adding a user account

You can see in Figure 13.3 that there are several team players involved in the account creation process. Notice that the /etc/skel directory is bolded. This is because, depending upon the other configuration files, it may not be used in the process. The same goes for the /home/ userid directory. It may not be created or it may have an alternative name, depending upon the system's account creation configuration. You'll learn more about these directories shortly.

Before we jump into the useradd utility details, let's look at the two files and the directory involved in the creation side of the process.

THE /ETC/LOGIN.DEFS FILE

This configuration file is typically installed by default on most Linux distributions. It contains directives for use in various shadow password suite commands. Shadow password suite is an umbrella term for commands dealing with account credentials, such as the useradd, userdel, and passwd commands.

The directives in this configuration file control password length, how long until the user is required to change the account's password, whether a home directory is created by default, and so on. The file is typically filled with comments and commented‐out directives (which make the directives inactive). The following snipped output shows some of the active directives within a /etc/login.defs file:

$ cat /etc/login.defs
[…]
MAIL_DIR        /var/spool/mail
[…]
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7
[…]
UID_MIN                 1000
UID_MAX                60000
[…]
SYS_UID_MIN              201
SYS_UID_MAX              999
[…]
GID_MIN                 1000
GID_MAX                60000
[…]
SYS_GID_MIN              201
SYS_GID_MAX              999
[…]
CREATE_HOME     yes
[…]
$

Notice the UID_MIN directive within the preceding example. A user identification number (UID) is the number used by Linux to identify user accounts. A user account, sometimes called a normal or standard account, is any account an authorized person has been given to access the system, with the appropriate credentials, and perform daily tasks. While humans use account names, Linux uses UIDs. The UID_MIN indicates the lowest UID allowed for user accounts. On the system, UID_MIN is set to 1000. This is typical, though some systems set it at 500.

System accounts are accounts that provide services (daemons) or perform special tasks. According to the settings in the previous example file, a system account's minimum UID is set by the SYS_UID_MIN, and its maximum is set by the SYS_UID_MAX directive.

Table 13.3 covers some additional /etc/login.def settings that are critical to common user account creation.

TABLE 13.3: A Few Vital /etc/login.defs Directives

Name Description
PASS_MAX_DAYS Number of days until a password change is required. This is the password's expiration date.
PASS_MIN_DAYS Number of days after a password is changed until the password may be changed again
PASS_MIN_LENGTH Minimum number of characters required in a password
PASS_WARN_AGE Number of days a warning is issued to the user prior to a password's expiration
CREATE_HOME Default is no. If set to yes, a user account home directory is created.
ENCRYPT_METHOD The method used to hash account passwords

THE /ETC/DEFAULT/USERADD FILE

The /etc/default/useradd file is another configuration file that directs the process of creating accounts. It typically is a much shorter file than the /etc/login.defs file.

$ cat /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
$
$ useradd ‐D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
$

Notice that there are two different ways to display the active directives in this file. You can use the cat command or invoke the useradd ‐D command. Both are equally simple to use. One cool fact about the useradd ‐D command is that you can use it to modify the directives within the /etc/default/useradd file.

Also in the preceding example, notice the HOME directive. It is currently set to /home, which means that any newly created user accounts will have their account directories located within the /home directory. Keep in mind that if CREATE_HOME is not set or set to no within the /etc/login.defs file, a home directory is not created by default.

Some additional directives are critical to common user account creation. These are covered briefly in Table 13.4.

TABLE 13.4: A Few Vital /etc/default/useradd Directives

NAME DESCRIPTION
HOME Base directory for user account directories
INACTIVE Number of days after a password has expired and has not been changed until the account will be deactivated. See PASS_MAX_DAYS in Table 13.3.
SKEL The skeleton directory
SHELL User account default shell program

The SHELL directive needs a little more explanation. Typically it is set to /bin/bash, which means when you access the command line, your user process is running the /bin/bash shell program. This program provides you with the prompt at the command line and handles any commands you enter there.

THE /ETC/SKEL/ DIRECTORY

The /etc/skel directory, or the skeleton directory (see Figure 13.3) as it is commonly called, holds files. If a home directory is created for a user, these files are to be copied to the user account's home directory when the account is created. The following shows the files within the /etc/skel directory:

$ ls ‐a /etc/skel
. .. .bash_logout .bash_profile .bashrc
$

The ls command output shows three files. These particular files are environment files. We'll cover environment files later in this chapter. In the /etc/skel directory, you can modify any of these files or add new files and directories to meet your particular system's needs.

Now that we've covered the files in the creation side of the user account creation process, let's look at the files and directories that are built or modified when an account is created.

THE /ETC/PASSWD FILE

Account information is stored in the /etc/passwd file. Each account's data occupies a single line in the file. When an account is created, a new record for that account is added to the /etc/passwd file.

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
[…]
sysadmin:x:1000:1000:Christine Bresnahan:/home/sysadmin:/bin/bash
$

The /etc/passwd records contain several fields. Each field in a record is delimited by a colon (:). Table 13.5 describes the seven fields in a /etc/passwd record.

TABLE 13.5: The /etc/passwd File's Record Fields

FIELD NO. DESCRIPTION
1 User account's username
2 Password field. Typically this file is no longer used to store passwords. An x in this field indicates passwords are stored in the /etc/shadow file.
3 User account's user identification number (UID)
4 User account's group identification number (GID)
5 Comment field. This field is optional. Usually, it contains the user's full name.
6 User account's home directory
7 User account's default shell. If set to /sbin/nologin or /bin/false, then the user cannot interactively log into the system.

You would think that the password file would hold passwords, but because of its file permissions, the password file can be compromised. Therefore, passwords are stored in the more permission‐restricted /etc/shadow file.

THE /ETC/SHADOW FILE

Another file that is updated when an account is created is the /etc/shadow file. It contains information regarding the account's password, even if you have not yet provided a password for the account. Like the /etc/passwd file, each account's data occupies a single file line. Because the file is more protected than the password file, you'll need to either use the root account or use the super user privileges to view it.

# cat /etc/shadow
root:[…]::0:99999:7:::
bin:*:18358:0:99999:7:::
daemon:*:18358:0:99999:7::: 
[…]
tcpdump:!!:18565::::::
sysadmin:[…]::0:99999:7:::$

The /etc/shadow records contain several fields. Each field in a record is delimited by a colon (:). There are nine fields in total, described in Table 13.6.

TABLE 13.6: The /etc/shadow File's Record Fields

FIELD NO. DESCRIPTION
1 User account's username
2 Password field. The password is a salted and hashed password. A !! or ! indicates a password has not been set for the account. A ! or * indicates the account cannot use a password to log in. A ! in front of a password indicates the account has been locked.
3 Date of last password change in Unix epoch time (days) format
4 Number of days after a password is changed until the password may be changed again
5 Number of days until a password change is required. This is the password's expiration date
6 Number of days a warning is issued to the user prior to a password's expiration (See field 5.)
7 Number of days after a password has expired (see field 5) and has not been changed until the account will be deactivated
8 Date of account's expiration in Unix epoch time (days) format
9 Called the special flag. It is a field for a special future use, is currently not used, and is blank.

Notice that field 1 is the account's username. This is the only field shared with the /etc/passwd file.

It's vital to understand the different possible expirations. When password expiration has occurred, there is a grace period. The user will have a certain number of days (designated in field 7) to log into the account using the old password but must change the password immediately. However, if password expiration has occurred and the user does not log in to the system in time, the user is effectively locked out of the system.

With account expiration, there is no grace period. After the account expires, the user cannot log into the account with its password.

You may have noticed that we have not yet covered the /etc/group file. It does get modified as part of the account creation process. However, that discussion is saved for the section “Managing Groups” later in this chapter.

CREATING AN ACCOUNT

The useradd command is the primary tool for creating user accounts on most distributions. This utility has many useful options for various needs, and Table 13.7 lists the most typical ones.

TABLE 13.7: The useradd Command's Commonly Used Options

SHORT LONG DESCRIPTION
‐c ‐‐comment Comment field contents. Traditionally, it contains the user's full name. Optional.
‐d ‐‐home or
‐‐home‐dir
User's home directory specification. The default action is set by the HOME and CREATE_HOME directives.
‐D ‐‐defaults Display /etc/default/useradd directives.
‐e ‐‐expiredate Date of account's expiration in YYYY‐MM‐DD format. The default action is set by the EXPIRE directive.
‐f ‐‐inactive Number of days after a password has expired and has not been changed until the account will be deactivated. A ‐1 indicates the account will never be deactivated. The default action is set by the INACTIVE directive.
‐g ‐‐gid Account's group membership, which is active when the user logs into the system (default group)
‐G ‐‐groups Account's additional group memberships
‐m ‐‐create‐home If it does not exist, create the user account's home directory. The default action is set by the CREATE_HOME directive.
‐M N/A or
‐‐no‐create‐home
Do not create the user account's home directory. Default action is set by the CREATE_HOME directive.
‐s ‐‐shell Account's shell. Default action is set by the SHELL directive.
‐u ‐‐uid Account's user identification (UID) number
‐r ‐‐system Create a system account instead of a user account.

Distributions tend to vary greatly in their configuration when it comes to user accounts. Therefore, before you launch into creating accounts with the useradd utility, it's wise to review some directives within each distro's user account configuration files (see Table 13.3 and Table 13.4). That way, you'll know what useradd options you'll need to include when creating accounts.

Here, before creating an account, the CREATE_HOME and SHELL directives are checked on a Red Hat‐based distribution.

$ grep CREATE_HOME /etc/login.defs
CREATE_HOME   yes
$
$ useradd ‐D | grep SHELL
SHELL=/bin/bash
$

You can see on this distribution that the home directory will be created by default, because CREATE_HOME is set to yes. The SHELL directive is pointing to the Bash shell, /bin/bash, which is the typical shell for most interactive user accounts.

An example of creating an account on this Red Hat–based distribution with the useradd utility is shown here using the root user account:

# whoami
root
#
# useradd ‐c "Takoda A. Puddle" tpuddle
#

Because the Red Hat–based distribution we are using has the CREATE_HOME directive set to yes and SHELL set to /bin/bash, there is no need to include any useradd command options. However, we did use the ‐c option to include the user's full name in the account's /etc/passwd record. The argument following the useradd command, tpuddle, is the actual username of the account.

Once you've created an account, it's a good idea to make sure that records now exist for the new user account in both the /etc/passwd and /etc/shadow files. The getent command is helpful here. You'll need to log into the root user account or use super user privileges to see the shadow files.

# getent passwd tpuddle
tpuddle:x:1001:1001:Takoda A. Puddle:/home/tpuddle:/bin/bash
#
# getent shadow tpuddle
tpuddle:!!:18652:0:99999:7:::
#

A password hasn't been added to the tpuddle account yet. That is why its record in the /etc/shadow file shows !! in the file's second field (the password field). Refer to Table 13.6 for all the fields in the shadow file.

Let's take a look at creating an account on a different Linux distribution. The Ubuntu server distro does things a little differently. You can see that CREATE_HOME is not set, so it will default to no, and that the SHELL directive is set to /bin/sh instead of the Bash shell.

$ grep CREATE_HOME /etc/login.defs
$
$ useradd ‐D | grep SHELL
SHELL=/bin/sh
$

Because of these settings, when creating a user account on this Ubuntu distribution, if you want the account to have a home directory and use the Bash shell, you will need to employ additional useradd command options listed in Table 13.7. Here is an example:

$ sudo useradd ‐c "London K. Radford" ‐md /home/lradford \
> ‐s /bin/bash lradford
[sudo] password for sysadmin:
$

Notice in the example that four options are used along with the useradd command. Because this system does not have the CREATE_HOME directive set, the ‐m option is needed to force useradd to make a home directory for the account. The ‐d switch designates that the directory name should be /home/lradford. Because the SHELL directive is set to /bin/sh on this system, the ‐s option is needed to set the account's default shell to /bin/bash. And the ‐c option was used to add a full name in the account's /etc/passwd record contents.

Now that this account is created, let's check to ensure the useradd options worked correctly.

$ getent passwd lradford
lradford:x:1001:1001:London K. Radford:/home/lradford:/bin/bash
$
$ sudo getent shadow lradford
lradford:!:18653:0:99999:7:::
$
$ ls ‐a /home/lradford
. .. .bash_logout .bashrc .profile
$
$ ls ‐a /etc/skel
. .. .bash_logout .bashrc .profile
$

Notice that records now exist for the new user account in the passwd and shadow files. Also, a new directory was created, /home/lradford, which contains files from this distro's /etc/skel/ directory. Keep in mind at this point that no password has been added to the lradford account yet, and thus its record in the shadow file shows ! in the password field.

Maintaining Accounts

Throughout an account's lifetime, you'll need to make modifications to it. A user can join new workgroups, change their name, and/or have their home directory moved to a new location, which all require changes to their account.

MANAGING PASSWORDS

When you first create an interactive account, you should immediately afterward create a password for that account using the passwd utility. You can create or update an account's password by passing the username as an argument to the command. Here a password is created for the new lradford account on an Ubuntu distribution:

$ sudo passwd lradford
[sudo] password for sysadmin:
New password:
Retype new password:
passwd: password updated successfully
$

If you need to update your own account's password, just enter passwd with no additional command arguments. With the passwd utility, you can lock or unlock accounts, set an account's password to expired, delete an account's password, and so on. Table 13.8 shows the more commonly used passwd switches; all of these options require super user privileges.

TABLE 13.8: The passwd Command's Commonly Used Options

SHORT LONG DESCRIPTION
‐d ‐‐delete Removes the account's password
‐e ‐‐expire Sets an account's password as expired. The user is required to change the account password at next login.
‐i ‐‐inactive Sets the number of days after a password has expired and has not been changed until the account will be deactivated
‐l ‐‐lock Places an exclamation point (!) in front of the account's password within the /etc/shadow file, effectively preventing the user from logging into the system via using the account's password
‐n ‐‐minimum Sets the number of days after a password is changed until the password may be changed again
‐S ‐‐status Displays the account's password status
‐u ‐‐unlock Removes a placed exclamation point (!) from the account's password within the /etc/shadow file
‐w ‐‐warning or ‐‐warndays Sets the number of days a warning is issued to the user prior to a password's expiration
‐x ‐‐maximum or ‐‐maxdays Sets the number of days until a password change is required. This is the password's expiration date.

The chage utility displays password information, but in a more human‐readable format than viewing the records in the /etc/shadow file or using the getent shadow command. It does require super user privileges to operate.

$ sudo chage ‐l lradford
Last password change                                 : Jan 26, 2021
Password expires                                     : never
Password inactive                                    : never
Account expires                                      : never
Minimum number of days between password change       : 0
Maximum number of days between password change       : 99999
Number of days of warning before password expires    : 7
$

Notice that the password for this account never expires. Be sure to review your company's policies for password management to ensure that the accounts on your system are following them.

MODIFYING ACCOUNTS

Besides adding and managing passwords, the accounts on your systems may have additional changes needed. The utility employed to modify accounts is the usermod program. The type of user account modification(s) is determined by which options are used with the usermod utility. Table 13.9 shows the commonly used options.

TABLE 13.9: The usermod Command's Commonly Used Options

SHORT LONG DESCRIPTION
‐c ‐‐comment Modify the comment field contents.
‐d ‐‐home Set a new user home directory specification. Use with the ‐m option to move the current directory's files to the new location.
‐e ‐‐expiredate Modify the account's expiration date. Use YYYY‐MM‐DD format.
‐f ‐‐inactive Modify the number of days after a password has expired and has not been changed that the account will be deactivated. A ‐1 indicates the account will never be deactivated.
‐g ‐‐gid Change the account's default group membership.
‐G ‐‐groups Update the account's additional group memberships. If only specifying new group membership, use the ‐a option to avoid removing the other group memberships.
‐l ‐‐login Modify the account's username to the specified one. Does not modify the home directory
‐L ‐‐lock Lock the account by placing an exclamation point in front of the password within the account's /etc/shadow file record.
‐s ‐‐shell Change the account's shell.
‐u ‐‐uid Modify the account's user identification (UID) number.
‐U ‐‐unlock Unlock the account by removing the exclamation point from the front of the password within the account's /etc/shadow file record.

Notice that you can change an account's default group and provide memberships to additional groups. Accounts' groups are covered in detail later in this chapter.

Where usermod comes in really handy is in a situation where you've created an account but forgot to check the distribution's account creation configuration settings, such as on an Ubuntu distribution.

$ sudo useradd ‐md /home/tpuddle tpuddle
$
$ sudo getent passwd tpuddle
tpuddle:x:1002:1002::/home/tpuddle:/bin/sh
$
$ sudo usermod ‐s /bin/bash tpuddle
$
$ sudo getent passwd tpuddle
tpuddle:x:1002:1002::/home/tpuddle:/bin/bash
$

In the example, when the user account tpuddle is created and the account record is checked using the getent utility, it shows that the /bin/sh shell is being used instead of the Bash shell. To fix this problem, the usermod command is employed with the ‐s option, and the account's shell is modified to the /bin/bash shell instead.

Removing Accounts

Deleting an account on Linux is fairly simple. The userdel utility is the key tool in this task. The most common option to use is the ‐r switch. This option will delete the account's home directory tree and any files within it.

$ sudo ls ‐d /home/tpuddle
/home/tpuddle
$ sudo getent passwd tpuddle
tpuddle:x:1002:1002::/home/tpuddle:/bin/bash
$
$ sudo userdel ‐r tpuddle
userdel: tpuddle mail spool (/var/mail/tpuddle) not found
$
$ sudo ls ‐d /home/tpuddle
ls: cannot access '/home/tpuddle': No such file or directory
$ sudo getent passwd tpuddle
$

The first two commands in the example show that the /home/tpuddle directory exists and that the account does have a record within the /etc/passwd file. The third command includes the userdel ‐r command to delete the account as well as the home directory. Notice that an error message is generated stating that the /var/mail/tpuddle file could not be found. This is not a problem. It just means that this file was not created when the account was created. Finally, the last two commands show that both the /home/tpuddle directory was removed and that the /etc/passwd file no longer contains a record for the tpuddle account.

Adding, modifying, and deleting accounts are common system admin activities. So is managing a user's environment. We'll cover that topic next.

Maintaining the Environment

After a user authenticates with the Linux system and prior to reaching the Bash shell's command‐line prompt, the user environment is configured. This environment consists of environment variables, command aliases, and various other settings.

The user environment configuration is accomplished via environment files. These files contain Bash shell commands to perform the necessary operations and are covered in the following sections along with a few environment variable highlights.

Setting Environment Variables

The Bash shell uses a feature called environment variables to store information about the shell session and the working environment, which were covered in Chapter 6, “Working with the Shell.” While you can modify these variables on the fly as shown in Chapter 6, the focus here is on how these parameters are persistently set or modified for user login processes.

When you start a Bash shell by logging in to the Linux system, by default Bash checks several files for the configuration. These files are called environment files, which are sometimes called startup files. The environment files that Bash processes depend on the method you use to start the Bash shell. You can start a Bash shell in three ways.

  • As a default login shell, such as when logging into the system at a tty terminal
  • As an interactive shell that is started by spawning a subshell, such as when opening a terminal emulator in a Linux GUI
  • As a noninteractive shell (also called nonlogin shell) that is started, such as when running a shell script

The environment files are actually shell scripts. Shell scripting is covered more thoroughly in Chapter 19, “Writing Scripts.” The following sections take you through the various available environment files.

Exploring User Entries

There are four potential files found in the user's home directory, $HOME, that are environmental files. For a default login or interactive shell, the first file found in the following order is run, and the rest are ignored:

  • .bash_profile
  • .bash_login
  • .profile

Typically, the fourth file, .bashrc, is run from the file found in the preceding list. However, anytime a noninteractive shell is started, the .bashrc file is run.

In the following example, a user's directory is checked for all four environment files. Notice that two of them are not found. Therefore, only the .bash_profile and .bashrc files are employed on this system.

$ pwd
/home/sysadmin
$

$ ls .bash_profile .bash_login .profile .bashrc
ls: cannot access '.bash_login': No such file or directory
ls: cannot access '.profile': No such file or directory
.bash_profile .bashrc
$

If you want to modify your shell's primary prompt (PS1) persistently, you can do so via adding the modification to one of your local environment configuration files. Here a user has persistently modified their prompt by setting the PS1 environment variable within their .bash_profile file:

Bash Prompt: grep PS1 .bash_profile
PS1="Bash Prompt: "
Bash Prompt:

These individual user environment files are typically populated from the /etc/skel/ directory, depending on your account creation configuration settings. For future accounts, you can make changes to the skeleton environment files. Just keep in mind that any individual user who can access the command line has the ability to modify their own files. Thus, for environment configurations that need to apply to all users, it is better to make a global entry in one of the global environment files, which are covered next.

Exploring Global Entries

Global configuration files modify the working environment and shell sessions for all users starting a Bash shell. As mentioned earlier, the global entries in these files can be modified by the account user via adding user entries into their $HOME environment files.

The global environment files consist of the following:

  • The /etc/profile file
  • Files within the /etc/profile.d/ directory
  • The /etc/bashrc or the /etc/bash.bashrc file

Whether your Linux system has the /etc/bashrc or the /etc/bash.bashrc file depends on which distribution you are running. Either file is typically called from the user's $HOME/.bashrc file.

It is recommended that instead of changing the /etc/profile or other files for global environment needs, you create a custom environment file, give it a .sh file extension, and place it in the /etc/profile.d/ directory. All the .sh files within the /etc/profile.d/ directory are run via the /etc/profile environment file for logins to the Bash shell.

Besides managing a user's environment, you also need to manage their groups. We'll explore that subject next.

Managing Groups

Groups are an organizational structure that is a part of Linux's discretionary access control (DAC). DAC is the traditional Linux security control, where access to a file, or any object, is based upon the user's identity and current group membership. When a user account is created, it is given membership to a particular group, called the account's default group. Though a user account can have lots of group memberships, its process can have only one designated current group at a time. The default group is an account's current group, when the user first logs into the system.

Groups are identified by their name as well as their group identification number (GID). This is similar to how users are identified by UIDs in that the GID is used by Linux to identify a particular group, while humans use group names.

If a default group is not designated when a user account is created, then a new group is created. This new group has the same name as the user account's name, and it is assigned a new GID. To see an account's default group, use the getent command to view the /etc/passwd record for that account. The fourth field in the record is the GID for the account's default group.

$ getent passwd lradford
lradford:x:1001:1001:London K. Radford:/home/lradford:/bin/bash
$
$ sudo groups lradford
[sudo] password for sysadmin:
lradford : lradford
$
$ getent group lradford
lradford:x:1001:
$
$ grep 1001 /etc/group
lradford:x:1001:
$

The first command shows that the lradford account's default group has a GID of 1001, but it does not provide a group name. The groups command does show the group name, which is the same as the user account name, lradford. This is typical when no default group was designated at account creation time. The third command, another getent command, shows that the group lradford does indeed map to the 1001 GID. The fourth command confirms this information.

Adding Groups

To add a user to a new group or change the account's default group, the group must preexist. This task is accomplished via the groupadd utility and super user privileges.

$ sudo groupadd training
$
$ getent group training
training:x:1002:
$

The getent utility shows the new group record in the group file. The fields in the /etc/group file are delimited by a colon (:) and are as follows:

  • Group name
  • Group password (An x indicates that, if a group password exists, it is stored in the /etc/gshadow file.)
  • GID
  • Group members (user accounts that belong to the group, separated by a comma)

Once a new group is created, you can add individual members to the group with the usermod command.

$ sudo groups lradford
lradford : lradford
$
$ sudo usermod ‐aG training lradford
$
$ sudo groups lradford
lradford : lradford training
$
$ getent group training
training:x:1002:lradford
$

Notice that the usermod command uses two options, ‐aG. The ‐G adds the lradford account as a member of the training group, but the ‐a switch is important because it preserves any previous lradford account group memberships. After the lradford account is added as a training group member, you can see in the last two command results that the /etc/group file record for training was updated.

For a user to access a group that they are a member of when it is not their default or current group, they need to use a special command, newgrp. View your current group via the id ‐gn command; then switch your current group with the newgrp command.

$ whoami
lradford
$
$ id ‐gn
lradford
$
$ newgrp training
$
$ id ‐gn
training
$
$ groups
training lradford
$

Notice that after the newgrp command was used, the id ‐gn command shows that training is the current group for the lradford account. You can also see all your group memberships along with the current group through the groups command. Your current group is the first one in the displayed list.

For an account user to change back to their default group, they can use newgrp again followed by the group's name. Alternatively, the exit command will also switch a user back to the default group, because newgrp creates a new user process when it is used.

Removing Groups

To remove a group, use the groupdel utility.

$ sudo groupdel training
$
$ getent group training
$
$ sudo groups lradford
lradford : lradford
$

Notice that after the training group is deleted, the getent command shows that the training group record has been removed from the /etc/group file. What is really nice is that any member of that deleted group has also had their group information updated as shown in the third command.

Now that you can add and managing user accounts and their environments, you can start to increase the number of users on your Linux systems. You also can set up more groups to refine access to various files and directories within the virtual directory structure.

The Bottom Line

  • Change a file's owner. A file or directory owner setting allows certain control over that file or directory. Some control is dictated by the permissions set at the owner level, but also only certain commands can be used on a file or directory by its owner. For example, you cannot change the group on a file if you do not own it (or don't have super user privileges).
    • Master It Imagine you are either logged into the root account or have access to super user privileges, and you have a copied a file projectData.txt to the lradford home directory. This user will need access to the file, which includes being able to change its group. What command syntax should you employ to accomplish this task?
  • Create user accounts. The useradd command is a command at the basic system level that allows you to create new accounts on the system. The needed various options are often determined by settings in the /etc/login.defs and the /etc/default/useradd files.
    • Master It You need to create a new account for a newly hired project manager, Takoda Puddle, who needs access to the Bash shell on your server. In your system's /etc/login.defs, you find that CREATE_HOME is defined as no, and UID_MIN is set to 1000. Within the /etc/default/useradd file, SHELL is defined as /bin/bash, and SKEL is set to the /etc/skel directory. The user's home directory should end up being /home/tpuddle. Assuming you are either logged into the root account or have access to super user privileges, what is the command syntax to create an account for the new project manager?
  • Modify a user's password. The passwd command along with the correct privileges allows you to create an account's password. However, besides just creating a password, you can change an account's password, delete its password, force a user to change their password at the next login, and so on. In addition, without any extra privileges, you can modify your own account's password through the passwd command.
    • Master It You are the system administration for several Linux servers at your company. An HR representative and your boss have come to your office to let you know that a fellow employee, Jay Snow, is being fired from the company. They have asked you to lock the jsnow account while they wait. What command do you enter to lock this account?
  • Find an environment file. Environment files on your system consist of both global files and local user files. Which environment files reside on a system depends on the Linux distribution being used. Global files reside in the /etc/ directory, and local user files reside in each user's home directory after being copied from the /etc/skel/ directory, if your system is configured to do so.
    • Master It You are the system admin for a development system. A programmer recently asked how a particular environment variable can be redefined, not only when they log into the system, but also when they run various Bash shell scripts on the system. What should you do or suggest?
  • Delete a user group. Managing groups of users on a Linux system is an important task. Several groups are permanent once created, but other groups, such as those related to special work projects, may come and go. You need to know how to create, modify, and even remove a user group.
    • Master It A small development project, abc123, on the system you administer has come to an end. The project files are no longer needed by the former team, and you've been asked to change the group on these project files to the manager group. Once you've completed that task, you'll need to remove the old abc123 project group. What is the command to accomplish this removal task?