Account lockouts in Unix/Linux systems can occur through multiple channels. Here are the primary methods:
# Common lockout indicators in /etc/shadow (second field):
* : Account disabled
! : Password locked
!! : Account never had password
$6$... : Normal encrypted password
The most common lockout scenario involves password expiration policies:
# Check password aging status
chage -l username
# Common expiration-related files:
/etc/login.defs # Password aging defaults
/etc/default/useradd # Account creation defaults
PAM modules like pam_tally2
or pam_faillock
can lock accounts:
# Check failed attempts (pam_tally2)
pam_tally2 --user=username
# Reset counter
pam_tally2 --user=username --reset
# For systems using faillock:
faillock --user username
faillock --user username --reset
Administrators can explicitly lock accounts:
# Using usermod
usermod -L username # Lock
usermod -U username # Unlock
# Using passwd
passwd -l username # Lock
passwd -u username # Unlock
SSH has its own lockout mechanisms:
# Check SSH deny rules
grep username /etc/ssh/sshd_deny
grep DenyUsers /etc/ssh/sshd_config
Some systems enforce additional restrictions:
# Check account accessibility
groups username
id username
# Verify PAM stack
ls -l /etc/pam.d/
cat /etc/pam.d/system-auth
Here's a comprehensive check script:
#!/bin/bash
USERNAME=$1
echo "=== Account Status Check for $USERNAME ==="
# Shadow file check
echo -n "Shadow status: "
grep "^$USERNAME:" /etc/shadow | cut -d: -f2 | cut -c1-3
# Password aging
echo "Password aging:"
chage -l $USERNAME
# Failed attempts
if which pam_tally2 &>/dev/null; then
echo "Failed attempts (pam_tally2):"
pam_tally2 --user=$USERNAME
fi
if which faillock &>/dev/null; then
echo "Failed attempts (faillock):"
faillock --user $USERNAME
fi
# Account locks
echo "Account locked (usermod/passwd):"
passwd -S $USERNAME
# SSH restrictions
echo "SSH restrictions:"
grep $USERNAME /etc/ssh/sshd_config
# Group memberships
echo "Group memberships:"
groups $USERNAME
MAC systems can prevent logins:
# Check SELinux context
semanage login -l | grep $USERNAME
# Verify AVC denials
ausearch -m avc -ts recent | grep $USERNAME
When facing an account lockout:
- Check
/etc/shadow
password field - Review
chage -l
output - Check PAM failure counters
- Verify manual locks (usermod/passwd)
- Inspect SSH restrictions
- Confirm group memberships
- Check SELinux/AppArmor contexts
Unix/Linux systems provide multiple layers of account security that can independently or cumulatively lock users out. The main mechanisms include:
- Password aging policies (/etc/shadow)
- Failed login attempt limits (pam_tally2/pam_faillock)
- Manual account locking (usermod -L or passwd -l)
- SSH key authentication failures
- SELinux/AppArmor restrictions
Use this systematic approach to identify all active lock conditions:
# 1. Check account status in /etc/shadow
sudo grep username /etc/shadow
# 2. Verify PAM failure counters
sudo pam_tally2 --user=username
# Or on newer systems:
sudo faillock --user username
# 3. Examine manual locks
sudo passwd -S username
# 4. Check secondary authentication systems
sudo ls /etc/security/access.conf
sudo ls /etc/security/time.conf
# 5. Verify PAM stack configuration
sudo cat /etc/pam.d/system-auth
sudo cat /etc/pam.d/sshd
1. Password Expiration
When /etc/shadow shows a password expiration:
username:$6$...:18648:5:90:7::18690:
The fields indicate password last changed (18648), minimum days (5), maximum days (90), and warning period (7). The account will lock after day 18648+90.
Solution:
sudo chage -E -1 username # Remove expiration
sudo chage -d $(date +%Y-%m-%d) username # Reset password age
2. Failed Attempt Lockouts
For pam_tally2 locked accounts (common on RHEL/CentOS):
# View failures
sudo pam_tally2 --user=username
# Reset counter
sudo pam_tally2 --user=username --reset
For pam_faillock (modern systems):
# View status
sudo faillock --user username
# Unlock
sudo faillock --user username --reset
3. Manual Account Locks
Check for explicit locks with:
sudo passwd -S username
# Output: username L 04/10/2023 0 99999 7 -1
The "L" indicates manual lock. Unlock with:
sudo usermod -U username
# Or:
sudo passwd -u username
PAM Stack Conflicts
Multiple PAM modules can interfere:
auth required pam_faillock.so preauth
auth sufficient pam_unix.so nullok try_first_pass
auth [default=die] pam_faillock.so authfail
Ensure your PAM configuration doesn't have duplicate or conflicting modules.
SSHD-Specific Issues
Check for these in /etc/ssh/sshd_config:
MaxAuthTries 3
PermitRootLogin prohibit-password
UsePAM yes
Excessive MaxAuthTries values with UsePAM=yes can create multiple lock conditions.
This bash script checks all common lock conditions:
#!/bin/bash
username=$1
echo "Checking lock status for $username"
# Shadow checks
echo -n "Shadow status: "
shadow_entry=$(sudo grep "^$username:" /etc/shadow)
if [[ -z "$shadow_entry" ]]; then
echo "User not found"
exit 1
fi
IFS=':' read -ra shadow_fields <<< "$shadow_entry"
if [[ "${shadow_fields[1]}" == "!"* || "${shadow_fields[1]}" == "*" ]]; then
echo "LOCKED (password disabled)"
fi
if [[ "${shadow_fields[7]}" != "" && "${shadow_fields[7]}" != -1 ]]; then
echo "LOCKED (account expired)"
fi
# PAM checks
if command -v pam_tally2 &> /dev/null; then
echo -n "PAM tally: "
sudo pam_tally2 --user=$username
fi
if command -v faillock &> /dev/null; then
echo -n "Faillock: "
sudo faillock --user $username
fi
# Manual lock check
echo -n "Passwd status: "
sudo passwd -S $username
Run with sudo privileges to get comprehensive lock status.