Account files and attributes
Listen to this lesson
This episode is a study companion for CompTIA Linux+ XK0-006 and is not produced by or endorsed by CompTIA.
Why this matters
The commands in the previous lesson are a front end. What they actually do is edit three text files. Once you can read those files directly you can diagnose account problems that the tools hide, audit a system quickly, and answer the question every auditor asks: who can log in to this machine, and who has administrative rights?
Identity is also less simple than it looks. A process runs with a real user ID and an effective one, and the gap between them is what makes sudo and passwd work at all.
The lesson
/etc/passwd
Despite the name, no passwords live here. It is world-readable, seven colon-separated fields per line.
alice:x:1001:1001:Alice Smith:/home/alice:/bin/bash
1 2 3 4 5 6 7
- Username
-
Password placeholder —
xmeans the hash is in/etc/shadow - UID — the user ID
- GID — the primary group ID
- GECOS — comment field, conventionally the full name
- Home directory
-
Login shell —
/usr/sbin/nologinhere means no interactive login
An x in field 2 is the normal, safe case. A hash sitting directly in that field is a serious finding, because the file is readable by every user.
/etc/shadow
The hashes, readable only by root.
alice:$6$xyz...:19700:7:90:14:30::
1 2 3 4 5 6 7 8 9
- Username
-
Hashed password — the
$6$prefix means SHA-512.!or!!at the start means locked;*means password login was never enabled - Days since 1 Jan 1970 that the password was last changed — the field
chage -d 0sets to zero - Minimum days before it may be changed again
- Maximum days before it must be changed
- Warning period in days
- Inactivity period after expiry
- Account expiry date
- Reserved
Fields 3–8 are exactly what chage reads and writes; chage -l is simply a readable rendering of this line.
/etc/group
developers:x:5000:alice,bob
Group name, placeholder, GID, and a comma-separated list of supplementary members.
The catch that confuses everyone: a user's primary group does not appear in this member list. Alice's primary group is field 4 of her /etc/passwd entry. So reading /etc/group alone under-reports membership, and "alice isn't in the developers group" is often wrong for exactly that reason. id alice gives the true answer.
(/etc/gshadow holds group passwords and administrators. It exists; it is rarely used.)
Never edit these files with a plain editor while others are logged in. Use vipw, vipw -s and vigr, which lock the file and validate on save.
UID and GID ranges
| Range | Meaning |
|---|---|
| 0 | root. The only thing that makes root special |
| 1–999 | System and service accounts |
| 1000+ | Regular human users (500+ on much older systems) |
UID 0 is root. Not the name — the number. Any account with UID 0 has full privileges, which is why a second UID-0 account is a classic backdoor and one of the first things to check in an audit:
awk -F: '$3 == 0 {print $1}' /etc/passwd # should print exactly "root"
The ranges themselves are configured in /etc/login.defs as UID_MIN and UID_MAX.
Real, effective, and why passwd works
Every process carries several identities:
- UID — the real user ID; who launched it
- EUID — the effective user ID; whose permissions it is actually using
- GID / EGID — the same pair for groups
Normally they match. They diverge when a program has the setuid bit, which tells the kernel to run it with the file owner's identity instead of the caller's.
/usr/bin/passwd is owned by root and setuid. When alice runs it, the real UID stays 1001 while the effective UID becomes 0 — which is the only reason she can write to /etc/shadow, a file she cannot otherwise read. The program checks that she is only changing her own entry.
This is also why setuid binaries are audited so carefully: a bug in one is a direct route to root.
id # uid, gid and all groups for you
id alice # for another user
id -u # numeric UID only
id -un # username only
Who is here, and who has been
whoami # effective username — the answer under sudo is root
who # who is logged in right now, and from where
w # the same, plus what each is running and load average
users # bare list of logged-in names
last # login history, from /var/log/wtmp
last -n 20 alice # alice's last 20 logins
last reboot # reboot history — when did this box restart?
lastlog # the most recent login for EVERY account
lastb # FAILED login attempts, from /var/log/btmp
lastlog is the audit tool. It lists every account and when it last logged in, so "Never logged in" against a live account is the signature of one that should probably not exist. lastb answers the other half — repeated failures against one account is a brute-force attempt.
whoami versus id -un: both give the effective user, so under sudo both say root. To find who is actually behind a sudo session, $SUDO_USER holds the original name.
Listing accounts properly
cut -d: -f1 /etc/passwd # names, local file only
getent passwd # names from EVERY source
getent passwd alice # one entry
getent group developers
groups alice # alice's groups
getent is the correct tool and the one the exam wants. It queries the Name Service Switch, so it returns local users and anything from LDAP, SSSD, Active Directory or NIS. On a domain-joined machine cut -d: -f1 /etc/passwd will simply not list most of your users; getent passwd will. The sources and their order are configured in /etc/nsswitch.conf.
Profile templates: /etc/skel
When useradd -m creates a home directory, it copies the contents of /etc/skel into it. That is where a new user's default .bashrc, .bash_profile and .profile come from.
Put a file in /etc/skel and every subsequently created user gets a copy. It does not apply retroactively — existing users are untouched, which is the usual surprise.
For settings that must apply to everyone including existing users, use the system-wide files instead: /etc/profile and /etc/profile.d/*.sh for login shells, /etc/bash.bashrc for interactive ones. The division is worth holding: /etc/skel is a one-time template, /etc/profile is live configuration read at every login.
On the exam
-
/etc/passwdfield order — know that field 2 is a placeholder and field 7 is the shell.nologinthere means no interactive login. -
!at the start of the/etc/shadowhash means locked. - A user's primary group is not listed in
/etc/group. Useid. - UID 0 is root. Checking for a second UID-0 account is a standard audit step.
- EUID versus UID, and setuid as the mechanism —
passwdis the example. -
getent passwdsees LDAP and other sources; reading/etc/passwddoes not. -
/etc/skelis copied at account creation only, and never retroactively. -
lastbshows failed logins;lastlogshows the last login for every account.
Practise what you just read
1. What does the second field of an /etc/passwd line contain on a modern Linux system?
Select one
Show answer
C. /etc/passwd must be world-readable so that any process can map UIDs to names, which is why hashes were moved out to /etc/shadow, readable only by root. The x is a placeholder saying "look in shadow". The seven fields are username, placeholder, UID, GID, GECOS comment, home directory and shell.
2. A line in /etc/shadow begins "bob:!$6$...". What does the exclamation mark indicate?
Select one
Show answer
C. A leading ! or !! marks the password as locked -- no supplied password can produce a hash matching the stored string, so password authentication always fails. An asterisk means the same thing and is typical of service accounts. An empty second field means no password at all, which is far more dangerous and worth spotting in an audit.
3. Grepping /etc/group for alice shows no line containing her name, yet id shows she is in group developers. Why?
Select one
Show answer
C. A user's primary group is recorded as a GID in the fourth field of their /etc/passwd line, not as a member entry in /etc/group. Only supplementary memberships are listed there. This is exactly why id is the right tool for the question "what groups is this user in?" -- grepping the group file gives an incomplete and misleading answer.
8 more questions on this objective are part of the full course.
Hands-on labs
Part of the free CompTIA Linux+ XK0-006 course — 48 lessons and 82 hands-on labs.