User management can be performed in one of three ways: GUI, command line or directly modifying the configuration files.
To perform user management with the GUI we just need to install the package system-config-users. We will not cover this any further as the GUI should be easy enough to use.
To manage users with the command line or modifying the files directly, we will first get to know all files involved and their contents.
The /etc/passwd file consists of 7 fields separated by a colon.
root:~> 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
adm:x:3:4:adm:/var/adm:/sbin/nologin
[…]
oprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologin
marc:x:1000:1000:Marc:/home/marc:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
1. username
2. encrypted password or “x” if password is in /etc/shadow
3. UID or user ID
4. GID or group ID
5. Comment (full name, contact details, purpose of account, etc)
6. home directory
7. default shell
The encrypted password value should always be set to “x” meaning that it is in the shadow file. But it can also be…
– the encrypted password (not a good idea)
– “*” meaning the account is locked
– “*NP*” meaning that the password should be obtained from NIS+.
– if it is empty, then login to this account does not prompt for a password (not a good idea!)
The /etc/shadow file consists of 9 fields separated by colon.
root:~> cat /etc/shadow
root:6$vZYQnnSVS8UcFg6D$Kme4RzWVgEQceaRpsTqDG0Ro5ZCE7leWHhwtD6rMR77W2too9M1:16506:0:99999:7:::
bin:*:16195:0:99999:7:::
daemon:*:16195:0:99999:7:::
adm:*:16195:0:99999:7:::
lp:*:16195:0:99999:7:::
sync:*:16195:0:99999:7:::
shutdown:*:16195:0:99999:7:::
halt:*:16195:0:99999:7:::
[…]
1. username
2. encrypted password
3. date of last password change
4. minimum password age in days
5. maximum password age in days
6. password warning period in days
7. password inactivity period in days
8. account expiration date
9. unused field
The value of username should be one matching a record in /etc/passwd.
The value of encrypted password is the output of the crypt function with the password as input. It can also be a “!” meaning that the account is locked. However, any value that can’t be the output of the crypt function has the same effect: locking the account. If the string starts with a “!” followed by a hashed password, that password was the one in use before the account got locked (that needs to be known if the account was expired to avoid re-using the last password).
The value of date of last password change is set in days since the epoch. If it is set to 0, the user will be prompted for a password reset at next login. If it is empty, password aging is disabled.
The value of minimum password age determines the minimum number of days before the user can change its password. If set to 0 or empty, this restriction is disabled.
The value of maximum password age determines the maximum number of days before the user has to change its password. When this number is reached, the password will still be valid but the user will be prompted to change it. An empty field means that there is no password aging, warning or inactivity period. If the value of maximum password age is lower than minimum password age, the user won’t be able to change its password.
The value of password warning period determines the number of days before the password is due to expire when the user starts to get reminders to change its password. If empty or set to 0, no warning will be given.
The value of password inactivity period determines the number of days after the password has expired in which it still can be used. After this number of days has elapsed, the account is locked. An empty field means that password aging is not really enforced.
The value of account expiration date determines the date (days since epoch) in which the account should be locked/expired. An empty field means that the account is not supposed to expire. The value of 0 should not be used as it might be interpreted as if the account was due to expire in 01/01/1970.
The /etc/group file consists of 4 fields separated by colon.
root:~> cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:marc
[…]
1. groupname
2. encrypted password or “x” meaning password is in /etc/gshadow
3. GID or group ID
4. list of users that belong to this group
The /etc/gshadow file has 4 fields separated by a colon.
root:~> cat /etc/gshadow
root:::
bin:::
daemon:::
sys:::
adm:::
[…]
postfix:!::
sshd:!::
marc:!!::marc
apache:!::
The first field is the group name that must match a group name in /etc/group.
The second field is the encrypted password. If it is empty or with a string that could never be the output of the crypt function, the group can only be used by those users who already belong to it (ergo, it is not possible to use the newgrp to change the group).
The third field is the list of administrators who can change the password for the group.
The fourth is the list of members of the group.
Another must know file is /etc/login.defs. It defines some default values that apply to the shadow utilities.
Let’s get an overview of some useful parameters in that file:
• PASS_MAX_DAYS: maximum number of days a password may be used
• PASS_MIN_DAYS: minimum number of days a password may be used
• PASS_MIN_LEN: minimum length a password must have to be accepted
• PASS_WARN_AGE: number of days a warning is given before a password expires
• UID_MIN: minimum UID assigned by the useradd command
• UID_MAX: maximum UID assigned by the useradd command
• GID_MIN: minimum GID assigned by the groupadd command
• GID_MAX: maximum GID assigned by the groupadd command
• SYS_UID_MIN: minimum UID assigned by useradd to system accounts
• SYS_UID_MAX: maximum UID assigned by useradd to system accounts
• SYS_GID_MIN: minimum GID assigned by groupadd to system accounts
• SYS_GID_MAX: maximum GID assigned by groupadd to system accounts
• USERDEL_CMD: states the script to run when a user is deleted with the userdel command. This script is invoked with the username as the first and only argument and the script is meant to remove any at/cron/print jobs. By default this parameter is commented out so no script is invoked at user deletion time.
• CREATE_HOME: in RHEL7 home directories for new users are created by default (so default value is “yes”) unless the “m” option for useradd is used.
• DEFAULT_HOME: determines whether or not login is allowed if a “cd $HOME” to the user’s home folder cannot be performed. It’s set to “no” by default but if set to “yes”, a “cd /” would be executed if the $HOME folder is not available.
• UMASK: is set to 022 by default but can be changed.
• USERGROUPS_ENAB: by default it is set to “yes” and creates a personal group (same groupname as username) for those users created without a primary group. If set to “no”, the primary group will be set to the value of the GROUP parameter in /etc/default/useradd.
• ENCRYPT_METHOD: usually set to SHA512 and should not be touched.
• ENV_PATH: default PATH value for users (defaults to “/bin:/usr/bin”).
• ENV_SUPATH: default PATH value for superusers (defaults to “/sbin:/bin:/usr/sbin:/usr/bin”).
• FAIL_DELAY: seconds of wait after a login failure before reattempting authentication.
• FAILLOG_ENAB: enable logging and display /var/log/faillog login failure info.
• ISSUE_FILE: if defined, the contents of this file will be shown before each login attempt.
• LASTLOG_ENAB: enable logging and display of /var/log/lastlog login time info.
• LOG_OK_LOGINS: enable logging of successful logins.
• LOG_UNKFAIL_ENAB: enable display of unknown usernames when login failures are recorded.
• LOGIN_RETRIES: max number of password authentication attempts before account is locked.
• LOGIN_TIMEOUT: max time in seconds to authenticate.
• NOLOGINS_FILE: existence of the file stated here will inhibit nonroot logins.
• SULOG_FILE: if defined all su activity is logged to this file.
• SYSLOG_SG_ENAB: if set to “yes” it enables syslog logging of sg activity. Default is “no”.
• SYSLOG_SU_ENAB: if set to “yes” it enables syslog logging of su activity (irrespective of the value of SULOG_FILE). Default is “no”.
Setting the values above to reasonable values can save us from having to set them for every user created and can tighten the security of the system.
The file /etc/securetty lists the local terminals in which root access is allowed. By default all terminals are included so root access is allowed in all of them. By commenting out all or most of the terminals we can restrict root logins. But nowadays where most logins are remote, it might be of little added value. Furthermore, only the shadow-utils version of login enforces this check.
Another useful but rarely used file is /etc/security/access.conf. This file restricts the logins to local and networked users in a variety of ways. It consists of 3 elements:
1- plus “+” or minus “-” meaning access allowed or denied respectively
2- list of users, groups or the keyword “ALL”
3- list of tty names, host names, domain names, IPs, “ALL” or “LOCAL”
Let’s look at some examples to make sense of it. This first example denies access to everybody but root on terminal tty1.
– : ALL EXCEPT root : tty1
The next one denies the ability to shutdown the OS for all but local users belonging to the wheel group.
– : ALL EXCEPT (wheel) shutdown sync : LOCAL
The next one disallows logins to any user belonging to the wheel group unless it is a local login or comes from the .bogomips.net domain or its IP network.
– : wheel : ALL EXCEPT LOCAL .bogomips.net 192.168.0.0/24
We can be nasty and deny access to some accounts without exceptions…
– : john thomas nancy : ALL
Another configuration file that is critical to the stability of the system is /etc/security/limits.conf. This file and those under /etc/security/limits.d/ restrict the availability of resources to users/groups:
core → limits the core file size (KB)
data → max data size (KB)
fsize → maximum filesize (KB)
memlock → max lockedinmemory address space (KB)
nofile → max number of open file descriptors
rss → max resident set size (KB)
stack → max stack size (KB)
cpu → max CPU time (MIN)
nproc → max number of processes
as → address space limit (KB)
maxlogins → max number of logins for this user
maxsyslogins → max number of logins on the system
priority → the priority to run user process with
locks → max number of file locks the user can hold
sigpending → max number of pending signals
msgqueue → max memory used by POSIX message queues (bytes)
nice → max nice priority allowed to raise to values: [20, 19]
rtprio → max realtime priority
If we need to make ammendments, we should do so in the subdirectory /etc/security/limits.d and leave limits.conf untouched.
If we want to enforce some kind of password complexity (beyond /etc/login.defs PASS_MIN_LEN), we can use the file /etc/security/pwquality.conf. The options are explained in the file itself.
To ensure that securetty, access.conf & pwquality.conf are enforced we might need to change some settings in the Pluggable Authentication Modules files in the directory /etc/pam.d/. We will cover that later on in the PAM section.
The next two files to know would be /etc/profile and /etc/bashrc. The former is the first file that sets some environment variables such as PATH and umask for all users.
The file bashrc is run immediately after for all users whose shell is /bin/bash. This file sets the environment with global aliases & functions.
Neither of these two files should be modified unless there is a very good reason to do so. Instead, we can add scripts or modify existing ones in /etc/profile.d and /etc/skel.
Many applications and software packages add extra environment variables in the profile.d directory to avoid interference with existing software.
The same way, if we want to customise PATHs or aliases for all users, it is better to modify the scripts .bash_profile, .bashrc and .bash_logout in /etc/skel. The files .profile and .bash_profile are executed only once at login time (from another host or the local console). Whereas .bashrc is executed every time a user connects to a terminal. It is thus a common practice to make .bash_profile a simple link to .bashrc or to call it in some fashion.