Skip to content
Linux Administration
Lab 8 of 27·35mBeginner

Day 03: What a user account actually is

Build an account by hand, read every file that records it, and see why a service account has no shell and no password.

You need

  • A Linux system with sudo access

Do first

An account is not one thing. It is a row in /etc/passwd, a row in /etc/shadow, a group, a home directory, and a login shell — five facts that can each be wrong independently.

1. Create one and read every record it made

sudo useradd -m -s /bin/bash -c "Lab User" labuser
getent passwd labuser
sudo getent shadow labuser
getent group labuser
ls -ld /home/labuser

The passwd row is seven colon-separated fields: name, an x where the password used to live, uid, primary gid, comment, home, shell. The hash itself lives in shadow, which only root can read — that split is the entire reason /etc/passwd can stay world-readable.

Verify

getent passwd labuser | cut -d: -f1,6,7 # labuser:/home/labuser:/bin/bash

2. See that the account cannot log in yet

sudo getent shadow labuser | cut -d: -f2

The password field is ! or * — a value that no hash can ever equal, so password auth always fails. Set one:

echo 'labuser:LabPass123!' | sudo chpasswd
sudo getent shadow labuser | cut -d: -f2 | cut -c1-3

Now it starts with $y$ or $6$, naming the hash algorithm (yescrypt or SHA-512).

Verify

sudo getent shadow labuser | cut -d: -f2 | grep -q '^\$' && echo "hash set" # hash set

3. Look at what -m actually copied

ls -la /home/labuser
ls /etc/skel

useradd -m copies /etc/skel into the new home. Whatever you put in /etc/skel appears in every account created afterwards — the supported way to give every new user the same shell config.

Verify

ls -a /etc/skel | wc -l # 3 or more — . .. and at least one dotfile

4. Create a service account, the way a package would

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc
getent passwd appsvc
sudo -u appsvc echo "ran as appsvc"
sudo su - appsvc

The sudo -u works — the account can own and run processes. The su - fails with "This account is currently not available", because its shell is nologin. That is the point: the service can run, nobody can log in as it.

Notice the uid is below 1000. That range is the convention for system accounts and is what --system sets.

Verify

getent passwd appsvc | cut -d: -f3,7 # a uid below 1000, and /usr/sbin/nologin

5. Lock an account without deleting it

sudo usermod -L labuser
sudo getent shadow labuser | cut -d: -f2 | cut -c1-2
sudo usermod -U labuser
sudo getent shadow labuser | cut -d: -f2 | cut -c1-2

-L prefixes the hash with !, which no input can produce, so password login fails while everything else about the account survives. -U removes the prefix. This is what you do when someone leaves and you are not yet ready to delete their files.

Locking the password does not disable SSH key auth. To stop all access you must also expire the account:

sudo usermod --expiredate 1 labuser
sudo getent shadow labuser | cut -d: -f8

Verify

sudo getent shadow labuser | cut -d: -f8 # 1 — the account is expired regardless of auth method

Clean up

sudo userdel -r labuser
sudo userdel appsvc

Where this goes next

You can create, lock and expire accounts. Tomorrow: the permission bits that are not rwx — the ones that decide what new files look like and let one program act as another user.