The /etc/passwd file explained

/etc/passwd is a text database of local user accounts. Each line is one account, with 7 colon-separated fields:

ruby

CopyEdit

login_name:password:UID:GID:GECOS:home_directory:login_shell

Example:

ruby

CopyEdit

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

norm:x:1001:1001:Normand Lavigne,,,:/home/norm:/bin/bash

Field-by-field

  1. login_name
    The username (unique). Typically lowercase letters, digits, _ or -. Max length varies by libc (often up to 32 chars).
  2. password
    • On modern systems you’ll see x: the real password hash is kept in /etc/shadow.
    • ! or a leading ! in shadow means the account is locked (password auth disabled).
    • * can also indicate “no password login”/not usable.
    • Historically this field held the hash directly (rare now).
  3. UID (User ID)
    • 0 is root (superuser).
    • System/service accounts use low numbers.
      • On many distros: 1–999 system users; 1000+ normal logins (RHEL/Debian-family defaults).
    • Must be unique; the kernel and file ownerships use UIDs, not names.
  4. GID (Primary Group ID)
    The user’s primary group (maps to an entry in /etc/group). Supplementary groups live in /etc/group and are not listed here.
  5. GECOS (User info / comment)
    Free-form, but traditionally comma-separated subfields:

pgsql

CopyEdit

Full Name,Room,Work Phone,Home Phone,Other

Tools like chfn edit this. Many systems only use the Full Name.

  1. home_directory
    User’s home (e.g., /home/norm). Must exist and have proper ownership/permissions.
  2. login_shell
    Program run after login: e.g., /bin/bash, /bin/zsh, /bin/sh.
    • /usr/sbin/nologin or /bin/false disables interactive logins for service accounts.

Permissions and related files

  • /etc/passwd is world-readable (-rw-r--r--, owner root:root), so it must not contain password hashes.
  • Password hashes and aging info live in /etc/shadow (-rw-------, root-only).
  • Group info is in /etc/group.

Best practices / admin tips

  • Don’t hand-edit with a normal editor; use vipw (locks safely). For groups, use vigr.
  • Prefer commands:
    • useradd, usermod, userdel
    • passwd (set/lock passwords), chage (password aging)
    • chfn (GECOS), chsh (shell)
  • Query safely with NSS (accounts may also come from LDAP/SSSD/NIS, not just the file):
    • getent passwd (lists all accounts from all configured sources)
    • getent passwd norm (one account)

Quick one-liners

  • List usernames and UIDs:

bash

CopyEdit

cut -d: -f1,3 /etc/passwd

  • Show users with a real shell (not nologin/false):

bash

CopyEdit

awk -F: '$7 ~ /(bash|zsh|fish|ksh|sh)$/ {print $1}' /etc/passwd

  • See a user’s full record (NSS-aware):

bash

CopyEdit

getent passwd norm

Common gotchas

  • Changing a user’s UID after files exist leaves files owned by the old UID; run chown -R newuid:newgid on their data.
  • A bad shell path (nonexistent or not executable) blocks logins.
  • Service accounts should use /usr/sbin/nologin and no home directory if not needed.
  • If your system uses LDAP/SSSD, a user may not appear in /etc/passwd but will still be returned by getent passwd.