The secrets of the usermod command
Most SysAdmins use a diverse set of commands, but it’s usually the same set of commands. And, most frequently, the same set of options for each of those commands.
Such is the case for me and the usermod command. I actually use it very seldom because I tend to modify most Linux configuration files directly using my favorite editor. And I seldom have need to modify a user account. The most common use cases for me are to change the comment (GECOS) field, to add the user to a group, or to lock the account. Of course I’ve also used my editor to do all those things. But this article is about the usermod command so we’ll explore that.
The shadow file
First, we need to know a little about the /etc/shadow file. We’ll do that by experimenting with a new account.
Make /etc the PWD for a root terminal session. I’ll use an account named tuser for the examples in this article. These commands must be run as root. If you don’t have an account, tuser, create it now.
# useradd -c "Test User" tuser
Check the /home directory to verify the account has been added.
# ll /home
total 32
drwxr-xr-x 88 dboth dboth 4096 Dec 12 09:56 dboth
drwx------. 2 root root 16384 Aug 6 04:38 lost+found
drwx------. 15 student student 4096 Sep 18 21:10 student
drwx------ 4 tuser tuser 4096 Sep 19 06:46 tuser
Look at the /etc/shadow file, which contains an entry for each user account on a Linux system. This includes many system accounts that are required for Linux services to run with a high level of security while not running as root. Account IDs are listed in apparently random order in the shadow file, The segment below is taken directly from the shadow file on one of my test VMs.
# cat shadow
<SNIP>
sshd:!:19827::::::
dnsmasq:!:19827::::::
tcpdump:!:19827::::::
passim:!*:19827::::::
dboth:$y$j9T$yMLfcJ6.nmuqw9frAvw73.$SwoXiZHQR3600GA7nD/EZy4M30N/QuX2/6sw8COpT0/:19966:0:99999:7:::
clamupdate:!:19884::::::
saslauth:!:19884::::::
mailnull:!:19884::::::
smmsp:!:19884::::::
dictd:!:19884::::::
boinc:!:19884::::::
student:$6$.N.Kuu3j8pu.WDZH$HyQeho4itMqwsy61PxiFwrOsDtCO8Km7jLDD0zQcvhL/LzB0zErHnr2zyrX/qIpMwhloegA4DcugUsNZnWYma0:19884:0:99999:7:::
sddm:!:19884::::::
firebird:!:19884::::::
flatpak:!:19959::::::
mysql:!:19959::::::
sssd:!:20094::::::
tuser:!:20096:0:99999:7:::
Despite its name, the /etc/passwd file does not contain any passwords. The /etc/shadow file is where the encrypted passwords are located. The nine fields in each line of the shadow file are separated by colons ( : ). The descriptions of these fields are summarized from the shadow(5) man page.
- login name — It must be a valid account name, which exist on the system.
- encrypted password — This field may be empty, in which case no passwords are required to authenticate as the specified login name. A password field which starts with an exclamation mark means that the password is locked. The remaining characters on the line represent the password field before the password was locked.
- date of last password change — The date of the last password change, expressed as the number of days since Jan 1, 1970 00:00 UTC. The value 0 has a special meaning, which is that the user should change their password the next time they log into the system. An empty field means that password aging features are disabled.
- minimum password age — The minimum password age is the number of days the user will have to wait before the password can be changed. This is used in conjunction with the pwhistory.conf file which remembers the specified number of previous passwords. It prevents users from changing the password quickly several times in order to use the same one again. An empty field and value 0 mean that there is no minimum password age.
- maximum password age — The maximum password age is the number of days after which the user will have to change their password. An empty field means that there are no maximum password age, no password warning period, and no password inactivity period.
- password warning period — The number of days before a password is going to expire (see the maximum password age above) during which the user should be warned. An empty field and value 0 mean that there are no password warning period.
- password inactivity period — The number of days after a password has expired (see the maximum password age above) during which the password should still be accepted (and the user should update their password during the next login).
You should view the shadow(5) man page for additional information. Notice that the shadow file does not contain the user ID or group ID of the account. It contains only the user name.
Locking the account
I locked the account using the -L option. Notice it uses uppercase L. Like most Linux commands, “Silence is Golden” when everything works as it should. When I did this the first time on the host I was testing, I’d forgotten that the tuser account had no password and that it was already locked.
# usermod -L tuser
Then I tried to unlock the account. But I ran into a problem. And silence is no longer an option so usermod displayed an error message.
# usermod -U tuser
usermod: unlocking the user's password would result in a passwordless account.
You should set a password with usermod -p to unlock this user's password.
root@vgr1:/home#
I’d created this account and never set a password. However the account was locked so it posed no security hazard. All new accounts created with the useradd command are locked, as are most of the system level accounts such as sshd, pipewire, tcpdump, dictd, and many more. look at your /etc/shadow file and look for the bang ( ! ) in the 2nd field. So the bottom line on this tuser account is that it was locked to start with.
The suggestion given to set the password for this account requires an encrypted password. It seems easier to use the passwd command, but this seems way more fun and interesting. There’s another interesting command that we can use to create the encrypted password, mkpasswd. You can read the details in my article, How I create encrypted passwords, but for now we’ll just use it as if I know what I’m doing.
I’ll use a single line command that both creates the password and adds it to the account. The obvious problem with this is that the password is visible and will be retained in the shell history.
# usermod -p `mkpasswd -m yescrypt MyPassword` tuser
Despite the message we received above, the usermod man page tells us not to set a password using this method. But it is interesting, which is why I did it on my test VM. Of course you can always edit or delete the .bash_history file. Now check the shadow file.
# cat shadow
<SNIP>
tuser:$y$j9T$vdB46/LvIMNvqwQRhwUMY/$C1O7J.QCaEUjRXqSHTuULUfRfbhnuA1l81BeT9696NC:20096:0:99999:7:::
Login to this account to verify that it works. And then lock the account.
# usermod -L tuser
Check the shadow file again.
# cat shadow | grep tuser
tuser:!$y$j9T$vdB46/LvIMNvqwQRhwUMY/$C1O7J.QCaEUjRXqSHTuULUfRfbhnuA1l81BeT9696NC:20096:0:99999:7:::
Notice the exclamation point (aka, bang) in the first position of the password field. That tells us that the account is locked. Try to login to verify this.
Now unlock the account
# usermod -U tuser
Again verify the account can be accessed.
Less ordinary uses
The usermod command can be used to make some other interesting modifications to user accounts.
One interesting usermod option is -d or –home. This can be used to specify a new home directory for an account. I’ve seen home directory locations that vary for Unix and Linux and some organizations used their own home directory standards instead of the standard ones as defined in the Linux Filesystem Hierarchical Standard. For example, instead of /home, one organization used /var/home. The -m option tells usermod to move all the data to the new home directory and -d defines the location of the new home directory. If the new home directory doesn’t exist, it will be created. Be sure to verify that the new location has enough space to contain all of the home directories that need to be moved.
# usermod -m -d /home/tuser tuser
Another situation is when a user is leaving the organization at a known date in the future. Using the -e (expire date) option can set a date in the future when the account will be disabled. This can be used when someone is going to retire to to leave the organization for other reasons and that departure date is known in advance.
# usermod -e 2026-05-21 tuser
Last words
In this article, we’ve looked at some of the interesting ways in which the usermod command can be used. The most common usage — for me at least — has been to lock and unlock accounts. We also looked at moving a user’s home directory and setting an account expiration date.
The usermod command has some other interesting capabilities that you can find in the man page.