passwd Command in Linux: Complete Guide to Password Management and Parameters

passwd command in Linux and it perimeters

passwd is one of the first commands most people learn on Linux, but the bare passwd invocation to change your own password is really just the front door — the command has a full policy-management side that most tutorials skip entirely: expiration, locking, aging rules, status reporting. I want to cover both halves properly, because the administrative side is what actually matters once you’re managing real users on a real system.

What passwd Does

passwd updates a user’s authentication token (their password) and, with the right flags, manages password aging and account lock state. It operates on /etc/shadow (the hashed password store) rather than /etc/passwd directly on any modern system — /etc/passwd itself hasn’t stored actual password hashes since the shadow password system became standard decades ago.

Syntax

passwd [options] [LOGIN]

Confirmed from passwd --help on a current Ubuntu 24.04 system:

Usage: passwd [options] [LOGIN]

Options:
  -a, --all                     report password status on all accounts
  -d, --delete                  delete the password for the named account
  -e, --expire                  force expire the password for the named account
  -h, --help                    display this help message and exit
  -k, --keep-tokens             change password only if expired
  -i, --inactive INACTIVE       set password inactive after expiration to INACTIVE
  -l, --lock                    lock the password of the named account
  -n, --mindays MIN_DAYS        set minimum number of days before password change
  -q, --quiet                   quiet mode
  -r, --repository REPOSITORY   change password in REPOSITORY repository
  -R, --root CHROOT_DIR         directory to chroot into
  -S, --status                  report password status on the named account
  -u, --unlock                  unlock the password of the named account
  -w, --warndays WARN_DAYS      set expiration warning days
  -x, --maxdays MAX_DAYS        set maximum number of days before password change

Parameters Explained in Depth

OptionPurpose
(no args)Change your own password interactively
LOGIN (as root)Change or manage the password of a specified user
-SReport password status: locked/usable, last change date, aging rules
-lLock the account by prefixing the password hash with !, blocking password authentication
-uReverse -l, unlocking the account
-eForce immediate expiration — the user must set a new password on next login
-n MINMinimum days that must pass before the password can be changed again
-x MAXMaximum days before the password expires and must be changed
-w WARNDays before expiration to start warning the user at login
-i INACTIVEDays after expiration before the account is fully disabled if no new password is set
-dRemove the password entirely (dangerous — allows passwordless login unless other auth is blocked)
-aReport status for all accounts (used with -S)

Tested Output: Status Reporting

$ passwd -S root
root L 2026-04-10 0 99999 7 -1

The fields, in order: username, status (L=locked, P=usable password set, NP=no password), date of last change, min days, max days, warn days, inactive days. This single line tells you everything about an account’s password policy at a glance, which makes passwd -S my go-to for auditing.

Common Administrative Workflows

Setting a password for a new user

useradd -m newuser
passwd newuser
New password:
Retype new password:
passwd: password updated successfully

Forcing a password change on next login

passwd -e newuser

I use this constantly for freshly provisioned accounts — set a known temporary password, then force the user to choose their own on first login rather than continuing to use one an admin knows.

Locking a compromised or departing employee’s account

passwd -l former_employee

This is the fast, immediate first step in an offboarding process — it prevents password-based login instantly, though note it does not kill existing active sessions or invalidate SSH keys, which need separate handling (pkill -u former_employee, revoking authorized_keys, disabling in any SSO/directory system).

Enforcing password aging policy

passwd -n 7 -x 90 -w 14 username

This sets: minimum 7 days between changes (prevents someone from cycling through required changes instantly back to their old password), maximum 90-day validity, and a 14-day advance warning before expiration.

Auditing every account’s status

passwd -Sa

Or, more targeted for scripting:

for user in $(cut -d: -f1 /etc/passwd); do
  passwd -S "$user" 2>/dev/null
done

How passwd Works Internally

When you set a password, passwd hashes it using the algorithm configured in /etc/login.defs (ENCRYPT_METHOD, typically SHA512 or increasingly yescrypt on newer distributions) combined with a randomly generated salt, then writes the result into /etc/shadow — never in plaintext, and never in /etc/passwd.

A typical /etc/shadow line:

username:$y$j9T$...(hash)...:19800:7:90:14:::

Fields, colon-separated: username, hashed password, days since epoch of last change, min days, max days, warn days, inactive days, expiration date, reserved field.

/etc/shadow is readable only by root (mode 640, group shadow on most distros) — this separation from the world-readable /etc/passwd is precisely why the shadow password system was introduced: it prevents unprivileged users from even accessing the hashes to run offline cracking attempts.

passwd itself is setuid-root (like su), because writing to /etc/shadow requires root privileges even when a regular user is only changing their own password. Behind that setuid boundary, PAM (/etc/pam.d/passwd) enforces password complexity rules via modules like pam_pwquality, rejecting weak passwords before they’re ever hashed and written.

Password Complexity Enforcement

On most modern distributions, pam_pwquality (successor to the older pam_cracklib) governs what passwd will accept interactively, configured in /etc/security/pwquality.conf:

minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
retry = 3

This enforces a minimum 12-character length with required digit, uppercase, lowercase, and special-character classes. Root bypasses these checks when setting another user’s password (an intentional administrative override), but a regular user changing their own password is subject to them.

Real-World Scripting Example: Bulk Onboarding

#!/bin/bash
set -euo pipefail
while IFS=, read -r username fullname; do
  useradd -m -c "$fullname" "$username"
  temp_pass=$(openssl rand -base64 12)
  echo "${username}:${temp_pass}" | chpasswd
  passwd -e "$username"
  echo "$username : $temp_pass" >> /root/new_accounts_$(date +%F).txt
done < new_hires.csv
chmod 600 /root/new_accounts_$(date +%F).txt

I use chpasswd rather than piping into passwd directly for bulk operations — it’s designed specifically for non-interactive batch password setting and avoids the prompt-driven interface passwd expects.

Troubleshooting

“passwd: Authentication token manipulation error” — often a full / or /var partition preventing the shadow file from being rewritten (it’s written atomically via a temp file and rename), or /etc/shadow has incorrect permissions/is read-only; check df -h and file permissions first.

User locked out but -S shows P (password set) — the lock may be happening elsewhere: check /etc/passwd for a shell of /sbin/nologin, check for SSH-specific restrictions (AllowUsers/DenyUsers in sshd_config), or PAM account restrictions (pam_time, pam_access) unrelated to the password itself.

Password change accepted by passwd but SSH key login still works — expected: locking a password (passwd -l) does not disable SSH public-key authentication, which is a separate mechanism entirely; for a full account lockdown, also handle authorized_keys and consider usermod -s /sbin/nologin.

“password expired, must change” at login blocking automated processes/cron jobs run as that user** — service accounts should generally have password aging disabled entirely: passwd -x -1 serviceaccount or a matching entry in /etc/login.defs defaults for system accounts.

Related Commands

CommandPurpose
passwdInteractive password changes and per-account policy management
chpasswdNon-interactive, batch password setting — reads user:password pairs from stdin
chageDedicated password aging management, a more detailed alternative to passwd -n/-x/-w/-i
usermod -L / -UAlternative lock/unlock mechanism, functionally similar to passwd -l/-u
pwckValidates the internal consistency of /etc/passwd and /etc/shadow
openssl passwdGenerates a standalone password hash outside the live user database, useful for pre-seeding /etc/shadow in automated provisioning (cloud-init, Kickstart)

chage -l username gives a more human-readable aging report than passwd -S if you want dates spelled out rather than the compact single-line format.

Security Implications

  • Never set passwords via command-line arguments to any tool in a way that lands in shell history or process listings (ps aux visible to other users) — chpasswd reading from stdin, or passwd interactively, are the safe patterns.
  • Lock (-l), don’t delete (-d), accounts you’re disabling — -d removes the password field entirely, which under certain misconfigurations can be interpreted as “no password required” rather than “cannot log in,” a dangerous ambiguity best avoided.
  • Rotate the password hashing algorithm forward when distributions update defaults (SHA512 to yescrypt, for example) — existing hashes aren’t automatically re-hashed, only newly-set passwords get the new algorithm, so a long-lived account’s hash might be using a weaker legacy scheme until its password is next changed.
  • Enforce aging policy (-x, -w) organization-wide via /etc/login.defs defaults for newly created accounts rather than relying on manually applying it per-user, which inevitably gets missed.

Distribution Compatibility

passwd is provided by shadow-utils (RHEL/Fedora naming) or passwd/login packages (Debian/Ubuntu naming) — functionally the same underlying shadow-password toolset across essentially every mainstream distribution, with consistent flag behavior. PAM module availability differs slightly: pam_pwquality is standard on RHEL/Fedora/recent Debian-Ubuntu, while older or minimal systems may still reference the deprecated pam_cracklib. Default hashing algorithm varies by distribution and release — check /etc/login.defs‘s ENCRYPT_METHOD directive rather than assuming.

Password Hashing Algorithm Evolution

It’s worth understanding how the hash format itself has evolved, since it directly affects what you’ll see in /etc/shadow and how secure existing hashes actually are. The leading $id$ prefix on a shadow hash identifies the algorithm used:

PrefixAlgorithm
$1$MD5 (obsolete, insecure by modern standards)
$5$SHA-256
$6$SHA-512 (long-standing default on most distributions)
$y$yescrypt (newer default on recent Debian/Ubuntu/Fedora releases, memory-hard and specifically designed to resist GPU-based cracking far better than SHA-512)

You can check which algorithm is configured as the default for newly-set passwords with:

grep ENCRYPT_METHOD /etc/login.defs

Because passwd only re-hashes a password when it’s actually changed, a long-lived account created years ago may still be carrying an older, weaker hash format even after the distribution’s default has moved on to something stronger — this is a legitimate reason to periodically enforce password rotation on old accounts, beyond the usual security-hygiene arguments for rotation.

Integrating passwd with Centralized Authentication

On systems joined to LDAP, FreeIPA, or Active Directory via SSSD, running plain passwd for a directory-managed account transparently routes the change through PAM to the central directory service rather than the local /etc/shadow file — the command-line interface stays identical, but the actual write target differs entirely depending on how NSS and PAM are configured (/etc/nsswitch.conf and /etc/pam.d/, respectively). This is worth confirming explicitly in mixed environments:

passwd -S someuser

If this reports LDAP or similar rather than expected local shadow-style output, or fails entirely, it’s a strong signal the account is centrally managed and any password policy questions (aging, complexity) need to be addressed on the directory server side, not through local /etc/login.defs tuning, which has no effect on directory-managed accounts.

The Historical Shift to Shadow Passwords

It’s worth briefly understanding why /etc/shadow exists as a separate file at all, since it explains several of passwd‘s permission-related behaviors. In very old Unix and early Linux systems, password hashes lived directly inside /etc/passwd, a file that had to remain world-readable because so many other tools relied on reading it for username/UID lookups. That meant every user’s password hash — even though it was hashed, not plaintext — was available for offline dictionary and brute-force attacks to anyone with any shell access at all. The shadow password suite split the sensitive hash data out into /etc/shadow, restricted to root (and the shadow group in some configurations, for tools like passwd that need read access without full root), while leaving /etc/passwd world-readable for the username/UID metadata everything else still needs. This split is why passwd must be setuid-root even for a user changing only their own password: writing to /etc/shadow requires privileges the calling user doesn’t otherwise have, entirely by design.

Summary

passwd is deceptively deep: the interactive password-change use case everyone learns first is a small fraction of what it actually manages — locking, expiration, aging policy, and status auditing are the parts that matter once you’re responsible for real user accounts on a real system. Understanding its relationship to /etc/shadow, PAM, and the setuid boundary it operates across explains both its behavior and why it deserves careful handling in any provisioning or offboarding automation.

References

  • Linux man-pages — passwd(1): https://man7.org/linux/man-pages/man1/passwd.1.html
  • Linux man-pages — shadow(5): https://man7.org/linux/man-pages/man5/shadow.5.html
  • Linux-PAM — pam_pwquality: https://man7.org/linux/man-pages/man8/pam_pwquality.8.html
  • Red Hat Documentation — Configuring Password Policies: https://access.redhat.com/documentation/
Total
0
Shares

Leave a Reply

Previous Post
id command in Linux and it perimeters

id Command in Linux: Complete Guide to User and Group Identification and Parameters

Next Post
su command in Linux and it perimeters

su Command in Linux: Complete Guide to Switching Users, Superuser Access, and Parameters

Related Posts