🔒 passwd Command

User Password and Account Management in Linux

About the passwd Command

The passwd command is used to change user passwords and manage password-related attributes in Linux and Unix systems. It provides both user-level functionality (changing your own password) and administrative capabilities (managing other users' passwords and account properties). The command interacts with the shadow password system to maintain secure, encrypted password storage.

Key capabilities: Changing passwords, locking and unlocking accounts, forcing password expiration, setting password aging policies, and managing account status. System administrators use passwd extensively for user account management and enforcing security policies.

Security context: Passwd is a setuid program, meaning it temporarily runs with root privileges even when executed by regular users. This allows users to modify their entries in /etc/shadow, which is normally only readable by root. The command includes extensive checks to ensure password quality and prevent weak passwords.

Basic Syntax:
passwd [OPTIONS] [USERNAME]

Common Usage:
passwd # Change your own password
sudo passwd username # Change another user's password
sudo passwd -l username # Lock a user account
sudo passwd -u username # Unlock a user account
sudo passwd -e username # Expire password, force change at next login
sudo passwd -d username # Delete password (dangerous!)
sudo passwd -S username # Display password status

Common Options:
-l, --lock Lock the password (disable account)
-u, --unlock Unlock the password
-d, --delete Delete the password (passwordless login)
-e, --expire Expire the password immediately
-S, --status Display account status information
-n, --mindays Set minimum days between password changes
-x, --maxdays Set maximum days password is valid
-w, --warndays Set warning days before password expires
-i, --inactive Set inactive days after expiration

Detailed Examples

1Change Your Own Password

The most common use of passwd - changing your own password as a regular user.

$ passwd
Changing password for craig. Current password: [entered but not displayed] New password: [entered but not displayed] Retype new password: [entered but not displayed] passwd: password updated successfully
What's happening: When a regular user runs passwd without arguments, it changes their own password. The process requires three steps:
(1) Enter current password for authentication - this prevents someone with temporary access to your terminal from changing your password.
(2) Enter new password - this is not displayed for security.
(3) Re-enter new password to confirm there were no typing errors. The passwords must match, and the new password must meet system complexity requirements (often defined in /etc/security/pwquality.conf or PAM configuration). If using libpwquality, weak passwords may be rejected with messages like "The password is too similar to the old one" or "The password fails the dictionary check."
Regular users can only change their own passwords. The passwd command validates the current password before allowing any changes, preventing unauthorized password modifications even if someone gains temporary access to an unlocked terminal.
Choose strong passwords: minimum 12-14 characters, mix of uppercase, lowercase, numbers, and symbols. Avoid dictionary words, personal information, and common patterns. Consider using a passphrase (e.g., "Coffee!Mornings@7am") which is both strong and memorable.

2Administrator Changes User Password

As root or with sudo, change another user's password without knowing their current password.

$ sudo passwd jdoe
New password: [entered but not displayed] Retype new password: [entered but not displayed] passwd: password updated successfully
What's happening: When root (or a user with sudo privileges) runs passwd with a username argument, they can set that user's password without knowing the current password. Notice that only two prompts appear - no "Current password" prompt because root has authority to change any password. This is essential for administrative tasks like password resets when users forget their passwords or for newly created accounts. The new password still must meet system complexity requirements unless root explicitly overrides them. This power should be used carefully and logged for security auditing. After changing a user's password as root, it's good practice to use passwd -e username to force the user to change it on next login.
Only administrators (root or sudo users) can change other users' passwords. This is a privileged operation and should be logged and audited. Consider your organization's password reset policies and whether the user should be forced to change the password at next login.
When performing password resets, verify the identity of the user requesting the reset through secure channels. Consider implementing a password reset workflow that forces immediate password change at next login and notifies the user via email or other secure communication.

3Check Password Status

Display detailed information about a user's password and account status.

$ sudo passwd -S jdoe
jdoe P 11/15/2025 7 90 7 30
What's happening: The -S (status) flag displays password aging information in a concise format. The output fields are: Username (jdoe), Password status (P = usable password, L = locked, NP = no password), Last change date (11/15/2025), Minimum days between changes (7), Maximum days before expiration (90), Warning period in days (7), and Inactivity period after expiration (30). This information comes from /etc/shadow. In this example, jdoe's password was last changed on November 15, 2025, they must wait 7 days before changing it again, it will expire after 90 days, they'll receive warnings 7 days before expiration, and after expiration they have 30 days of inactivity before the account is locked.

Related Files

/etc/shadow: Contains the actual password aging data that passwd -S displays. Fields correspond to: username:password:lastchange:min:max:warn:inactive:expire
Use passwd -S regularly to audit account status on your system. You can script this to check all users: for user in $(cut -d: -f1 /etc/passwd); do sudo passwd -S $user; done

4Lock a User Account

Disable a user account by locking the password, preventing login.

$ sudo passwd -l jdoe
passwd: password expiry information changed.
$ sudo passwd -S jdoe
jdoe L 11/15/2025 7 90 7 30
What's happening: The -l (lock) flag disables the account by prefixing the encrypted password in /etc/shadow with an exclamation mark (!). This makes the stored hash invalid, preventing password-based authentication. The status display now shows "L" instead of "P", confirming the account is locked. Important limitation: Locking the password only prevents password-based authentication. If the user has SSH keys configured in ~/.ssh/authorized_keys, they can still log in via SSH key authentication. The user's files and processes remain untouched. This is useful for temporarily disabling accounts during investigations or when employees are on extended leave. To fully disable account access, you'd also need to disable SSH keys and potentially kill active processes.
Account locking via passwd -l does NOT prevent SSH key-based authentication. If complete access denial is required, also remove or rename the user's .ssh/authorized_keys file, or use more comprehensive tools like usermod -L or consider using pam_access to deny all authentication methods.
Locking accounts is preferable to deleting them when you might need to restore access later. The user's files, crontabs, and other resources remain intact and ownership is preserved. Document why accounts are locked and review locked accounts periodically.

5Unlock a User Account

Re-enable a previously locked account by removing the lock.

$ sudo passwd -u jdoe
passwd: password expiry information changed.
$ sudo passwd -S jdoe
jdoe P 11/15/2025 7 90 7 30
What's happening: The -u (unlock) flag removes the lock by removing the "!" prefix from the password hash in /etc/shadow. The account status returns to "P" (usable password). The user can now log in with their password again. This is the counterpart to passwd -l. Important note: You cannot unlock an account that has no password set (NP status). If an account was created without a password or had its password deleted with passwd -d, unlocking will fail. You must first set a password with passwd username. Unlocking restores exactly the previous state - the same password that was active before locking becomes active again.
Before unlocking an account, verify the reason it was locked and ensure it's appropriate to restore access. Check logs for why the account was locked and document the unlock action. You might want to force a password change after unlocking with passwd -e username.

6Force Password Change at Next Login

Expire a user's password immediately, requiring them to change it on their next login.

$ sudo passwd -e jdoe
passwd: password expiry information changed.
$ sudo passwd -S jdoe
jdoe P 01/01/1970 7 90 7 30
What's happening: The -e (expire) flag sets the last password change date to the Unix epoch (January 1, 1970), making the password immediately expired. Notice the date field now shows 01/01/1970 instead of the actual last change date. When jdoe attempts to log in (via terminal, SSH, or any other method), they'll be immediately prompted to change their password before being allowed to continue. They cannot bypass this - the system will not grant access until a new password is set. This is extremely useful after:
(1) Creating new accounts (force users to set their own password),
(2) Administrative password resets (ensure users change temporary passwords),
(3) Security incidents (force password changes for potentially compromised accounts),
(4) Onboarding (ensure new employees set strong personal passwords).
Always use passwd -e after administratively resetting a user's password. This ensures the temporary password you set is immediately changed to something only the user knows. This is a security best practice that prevents administrators from having continued knowledge of user passwords.
Combine operations for secure password resets: sudo passwd username (set temporary password), then sudo passwd -e username (force change at login). Communicate the temporary password securely to the user, never via unencrypted email.

7Set Password Aging Policies

Configure minimum days, maximum days, and warning period for password expiration.

$ sudo passwd -n 7 -x 90 -w 14 jdoe
passwd: password expiry information changed.
$ sudo passwd -S jdoe
jdoe P 11/15/2025 7 90 14 30
What's happening: This command sets multiple password aging parameters simultaneously: -n 7 sets the minimum number of days between password changes to 7 (prevents users from immediately changing back to old passwords), -x 90 sets the maximum password age to 90 days (password expires after 90 days), and -w 14 sets the warning period to 14 days (users receive warnings starting 14 days before expiration). The status output now shows the updated values. These policies help enforce security best practices: regular password rotation (max days), preventing password cycling (min days), and giving users advance notice (warn days). When the password expires after 90 days, jdoe will be forced to change it. If they change their password, they must wait 7 days before changing it again, preventing the common pattern of repeatedly changing passwords to cycle back to a favorite one.
Password aging policies should align with your organization's security requirements and compliance mandates (HIPAA, PCI-DSS, etc.). Common values: 90-180 days maximum, 1-7 days minimum, 7-14 days warning. Balance security with usability - overly strict policies can lead to users writing down passwords.

System-wide Defaults

/etc/login.defs: Contains default password aging settings (PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_AGE) that apply to newly created users. Existing users must be updated individually with passwd or chage.

8Set Account Inactivity Period

Configure how long after password expiration the account remains accessible.

$ sudo passwd -i 30 jdoe
passwd: password expiry information changed.
$ sudo passwd -S jdoe
jdoe P 11/15/2025 7 90 14 30
What's happening: The -i 30 flag sets the inactivity period to 30 days. This defines a grace period after password expiration during which the user can still log in but must immediately change their password. After the password expires (at 90 days based on -x setting), jdoe has 30 additional days to log in and change it. If they don't log in within those 30 days, the account becomes locked and requires administrator intervention to unlock. This prevents long-term inactive accounts with expired passwords from remaining accessible. The inactivity period appears as the last field in the status output. This setting is particularly important for accounts that might go unused for periods - it ensures that expired passwords on inactive accounts don't remain as potential security vulnerabilities indefinitely.
The inactivity period provides a balance between security and user convenience. It gives users a grace period to log in after their password expires (useful if they're on vacation when it expires) while ensuring inactive accounts don't remain accessible indefinitely with expired credentials.
Common inactivity settings: 7-30 days for regular user accounts, shorter periods (1-7 days) for privileged accounts, longer periods (30-60 days) for accounts that are legitimately used infrequently. Consider your organization's usage patterns and security requirements.

9Delete Password (Passwordless Account)

Remove the password entirely, allowing login without password authentication.

$ sudo passwd -d testuser
passwd: password expiry information changed.
$ sudo passwd -S testuser
testuser NP 11/28/2025 0 99999 7 -1
What's happening: The -d (delete) flag removes the password hash from /etc/shadow, making the password field empty. The status now shows "NP" (no password) instead of "P" or "L". The account can potentially be accessed without providing a password, depending on PAM configuration and the authentication method used. Security implications: This is generally considered a significant security risk. However, it has legitimate uses:
(1) System accounts that should never be logged into directly,
(2) Accounts used only with SSH key authentication where password login is disabled in sshd_config,
(3) Kiosk or public terminal accounts in controlled environments.
Important: Many modern PAM configurations will still prevent login for accounts with no password, requiring additional configuration to actually enable passwordless login.
Removing passwords creates security vulnerabilities. Only use this for specific purposes like system service accounts that should never be used for login, or in conjunction with other security controls like SSH-key-only authentication. Never use this for regular user accounts. Most compliance frameworks explicitly prohibit passwordless accounts.
Even with no password, the account is not necessarily accessible without authentication. PAM configuration (in /etc/pam.d/) may still require authentication. The nullok option in PAM controls whether passwordless accounts are allowed to authenticate.

10Batch Password Policy Update

Update password policies for multiple users using a script.

$ cat update_password_policies.sh
#!/bin/bash # Update password aging policies for all regular users # (UIDs 1000 and above, excluding system accounts) echo "Updating password policies for regular users..." for user in $(awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwd); do echo "Processing user: $user" # Set password aging: min 7 days, max 90 days, warn 14 days, inactive 30 days passwd -n 7 -x 90 -w 14 -i 30 "$user" # Display new status passwd -S "$user" echo "---" done echo "Password policy update complete."
$ sudo bash update_password_policies.sh
Updating password policies for regular users... Processing user: jdoe passwd: password expiry information changed. jdoe P 11/15/2025 7 90 14 30 --- Processing user: alice passwd: password expiry information changed. alice P 10/20/2025 7 90 14 30 --- Processing user: bob passwd: password expiry information changed. bob P 11/01/2025 7 90 14 30 --- Password policy update complete.
What's happening: This script demonstrates batch password policy management. It uses awk to extract usernames from /etc/passwd for regular users (UID >= 1000 and < 65534, which typically represents normal user accounts rather than system accounts). For each user, it applies consistent password aging policies: 7-day minimum between changes, 90-day maximum age, 14-day warning period, and 30-day inactivity period. The script then displays the status for verification. This approach is essential for:
(1) Applying organization-wide security policies consistently,
(2) Ensuring compliance with security standards,
(3) Updating policies across many user accounts efficiently,
(4) Maintaining audit trails of policy changes.
The script can be enhanced to log changes, send notifications, handle exceptions, or read policies from a configuration file.
Batch updates should be carefully tested before production deployment. Run the script on a test system first, or modify it to show what would be changed without actually making changes (dry-run mode). Document the changes and notify users when password policies change, especially if passwords will expire sooner than previously configured.
Enhance this script by:
(1) Adding logging to /var/log/password_policy_changes.log,
(2) Excluding specific users or groups,
(3) Reading policy values from a config file,
(4) Sending email notifications to affected users,
(5) Creating a dry-run mode with --test flag,
(6) Adding error checking for each passwd command.

Complete Options Reference

Option Long Form Description
-a --all Show password status for all users (used with -S)
-d --delete Delete the user's password (make passwordless)
-e --expire Force user to change password at next login
-h --help Display help message and exit
-i DAYS --inactive DAYS Set inactive days after password expiration
-k --keep-tokens Keep authentication tokens (change only expired passwords)
-l --lock Lock the user account
-n DAYS --mindays DAYS Set minimum days between password changes
-q --quiet Quiet mode (minimal output)
-r --repository Change password in specified repository
-R --root Apply changes in specified chroot directory
-S --status Display account status information
-u --unlock Unlock the user account
-w DAYS --warndays DAYS Set warning days before password expires
-x DAYS --maxdays DAYS Set maximum days password is valid

Password Status Codes

Status Code Meaning Description
P Usable password The account has a valid password and can be used for authentication
L Locked password The password is locked with passwd -l (has ! prefix in /etc/shadow)
NP No password The account has no password set (empty password field in /etc/shadow)
LK Locked (no password) The account is locked and has no password

Related Files and System Integration

/etc/passwd

Purpose: Contains basic user account information
Format: username:x:UID:GID:comment:home:shell
Note: The "x" in the password field indicates the actual password hash is in /etc/shadow

/etc/shadow

Purpose: Contains encrypted passwords and password aging information
Format: username:password:lastchange:min:max:warn:inactive:expire:reserved
Permissions: -rw-r----- (root:shadow) - only readable by root and shadow group
Fields:
  • password: Encrypted password hash (or ! for locked, empty for no password)
  • lastchange: Days since Unix epoch when password was last changed
  • min: Minimum days between password changes
  • max: Maximum days before password must be changed
  • warn: Days before expiration to start warning user
  • inactive: Days after expiration before account is locked
  • expire: Absolute date when account expires (days since Unix epoch)

/etc/login.defs

Purpose: System-wide defaults for password aging and other login parameters
Key settings:
  • PASS_MAX_DAYS: Default maximum password age for new users
  • PASS_MIN_DAYS: Default minimum days between changes
  • PASS_WARN_AGE: Default warning period before expiration
  • PASS_MIN_LEN: Minimum acceptable password length (if not using PAM)
Note: These defaults apply only to newly created accounts, not existing ones

/etc/security/pwquality.conf

Purpose: Password quality requirements (when using pam_pwquality)
Common settings:
  • minlen: Minimum password length
  • dcredit: Required digits (negative = minimum, positive = bonus)
  • ucredit: Required uppercase letters
  • lcredit: Required lowercase letters
  • ocredit: Required special characters
  • difok: Number of characters that must be different from old password
  • maxrepeat: Maximum number of consecutive identical characters
  • gecoscheck: Check against GECOS field (user's full name)
  • dictcheck: Enable dictionary checking

/etc/pam.d/common-password (Debian/Ubuntu) or /etc/pam.d/system-auth (RHEL/CentOS)

Purpose: PAM configuration for password authentication
Controls: Password quality checking, password history, account restrictions
Example line: password requisite pam_pwquality.so retry=3

Best Practices and Security Guidelines

Password Security Best Practices

  • Enforce strong passwords: Configure pwquality or cracklib to require minimum complexity (12-14 characters, mixed case, numbers, symbols)
  • Implement password aging: Set reasonable maximum password age (60-90 days for regular users, 30-45 days for privileged accounts)
  • Prevent password reuse: Use PAM's pam_pwhistory to remember last 5-10 passwords and prevent reuse
  • Set minimum password age: Require 1-7 days between password changes to prevent users from rapidly cycling back to old passwords
  • Provide adequate warning: Set warning period to 7-14 days so users aren't surprised by expiration
  • Configure inactivity periods: Lock accounts after 30-60 days of inactivity following password expiration
  • Force password changes after resets: Always use passwd -e after administratively resetting passwords
  • Never use passwd -d for regular accounts: Passwordless accounts are security vulnerabilities
  • Monitor password policy compliance: Regularly audit accounts with passwd -S or chage -l
  • Document password policies: Ensure users understand password requirements and change procedures

Administrative Best Practices

  • Log all password changes: Ensure passwd operations are logged (usually to /var/log/auth.log or /var/log/secure)
  • Use secure communication for resets: Never send passwords via unencrypted email or instant messaging
  • Verify identity before resets: Implement strong identity verification for password reset requests
  • Review locked accounts regularly: Periodically audit locked accounts and document why they're locked
  • Implement account lifecycle policies: Define procedures for account creation, password management, and deactivation
  • Test password policies in non-production: Validate that new password policies work as expected before deployment
  • Consider multi-factor authentication: Passwords alone are insufficient for many security contexts
  • Maintain password policy documentation: Keep current documentation of all password requirements and procedures
  • Train users on password security: Educate users about creating strong, unique passwords and recognizing phishing
  • Comply with regulatory requirements: Ensure password policies meet HIPAA, PCI-DSS, SOX, or other applicable standards

Common Password Policy Examples

  • Standard corporate: 90 days max, 1 day min, 14 days warn, 30 days inactive, 12 char minimum with complexity
  • High security: 60 days max, 1 day min, 7 days warn, 14 days inactive, 14 char minimum with high complexity, no reuse of last 10
  • Privileged accounts: 30-45 days max, 1 day min, 7 days warn, 7 days inactive, 16 char minimum, no reuse of last 20
  • PCI-DSS compliant: 90 days max, 1 day min, 7 char minimum (though 12+ recommended), no reuse of last 4
  • HIPAA compliant: 90 days max (or less), unique last 5, adequate complexity, account lockout after failed attempts

Common Use Cases and Workflows

New User Account Setup

$ sudo useradd -m -s /bin/bash newuser
$ sudo passwd newuser
New password: [temporary password]
Retype new password: [temporary password]
$ sudo passwd -e newuser
$ sudo passwd -n 1 -x 90 -w 14 -i 30 newuser
Complete workflow: Create user, set temporary password, force password change at first login, configure password aging policies.

Secure Password Reset Process

$ sudo passwd jdoe
New password: [secure temporary password]
Retype new password: [secure temporary password]
$ sudo passwd -e jdoe
$ echo "Your password has been reset. Temporary password: [password]" | mail -s "Password Reset" jdoe@example.com
Reset password, force immediate change, notify user securely. In production, use encrypted communication channels.

Temporary Account Suspension

$ sudo passwd -l jdoe
$ sudo passwd -S jdoe # Verify locked status
$ echo "$(date): Account jdoe locked - reason: Extended leave" >> /var/log/account_changes.log
Lock account, verify status, document the action for audit purposes.

Account Reactivation

$ sudo passwd -u jdoe
$ sudo passwd -S jdoe # Verify unlocked
$ sudo passwd -e jdoe # Force password change for security
$ echo "$(date): Account jdoe unlocked and password expired" >> /var/log/account_changes.log
Unlock account, verify status, force password change as security measure, log the action.

Troubleshooting Common Issues

Error: "Authentication token manipulation error"
Causes: (1) /etc/shadow or /etc/passwd permissions incorrect, (2) Filesystem mounted read-only, (3) SELinux policy preventing changes, (4) Corrupted password file. Solutions: Check file permissions (shadow should be 640 or 400), verify filesystem is writable, check SELinux with sestatus, run pwck to validate password files.
Error: "passwd: Have exhausted maximum number of retries for service"
Cause: PAM configuration issue or system under heavy load. Solutions: Check /var/log/auth.log for detailed PAM errors, verify PAM modules are properly configured in /etc/pam.d/, ensure system has adequate resources.
Error: "passwd: User not known to the underlying authentication module"
Cause: User exists in /etc/passwd but not in the PAM authentication system (LDAP, NIS, etc.). Solution: Verify user exists in the configured authentication backend, check nsswitch.conf for proper service order.
Issue: Password immediately expires after being set
Cause: System clock is incorrect or password last-change date is in the future. Solution: Verify system time with date, check /etc/shadow entry for user, manually correct last-change field if necessary with chage -d.
Issue: Cannot unlock account (passwd -u fails)
Cause: Account has no password (NP status). Solution: Cannot unlock an account with no password. Must first set a password with passwd username, then the account will be usable.
Issue: User can still log in after passwd -l
Cause: User is using SSH key authentication, which bypasses password locking. Solutions: Remove or rename ~/.ssh/authorized_keys file, disable SSH key authentication in sshd_config for that user, or use more comprehensive tools like usermod -L which also prevents SSH key login on some systems.

Alternative Tools and Related Commands

  • chage: More comprehensive password aging management with additional options and better date handling
  • usermod: General user account modification including login shell, home directory, and groups
  • chpasswd: Batch password changes from standard input (useful for scripting multiple changes)
  • pwck: Verify integrity of password files (/etc/passwd and /etc/shadow)
  • getent passwd: Display password database entries (works with LDAP, NIS, local files)
  • faillock: Display and modify authentication failure records (account lockout from failed logins)
  • pam_tally2 / faillog: Older tools for managing failed login attempts
  • pwgen: Generate secure random passwords for initial account setup

Comparison: passwd vs. chage

While passwd handles password changes and basic aging, chage provides more comprehensive aging management:
Feature passwd chage
Change password ✓ Primary function ✗ Cannot change passwords
Set max days ✓ (passwd -x) ✓ (chage -M)
Set min days ✓ (passwd -n) ✓ (chage -m)
Interactive mode ✓ (chage username with no options)
Set expiration date ✓ (chage -E, accepts actual dates)
List account info Basic (passwd -S) Detailed (chage -l)
Date handling Days since epoch only Accepts dates in YYYY-MM-DD format
Use passwd for password changes and simple aging policies. Use chage for comprehensive account aging management, especially when you need to set specific expiration dates or want interactive configuration.