Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I recently added a bunch of users and gave them randomly generated passwords. We've since instructed them to change their passwords, but we suspect that a large number of them have not.

How can we expire the passwords of everyone who hasn't changed their password yet?

We're on Ubuntu 9.04 server using normal /etc/passwd authentication.

share|improve this question
up vote 4 down vote accepted

You can use the chage command to see the last time they changed their password, for example:

sudo chage -l kbrandt

You can mix that with a loop and awk of the /etc/passwd file, might be a better way though. Maybe something like:

while read line; do 
    date_change=$(echo $line | awk -F: '{print $3}')
    user=$(echo $line | awk -F: '{print $1}')
    #Say you set them on 14120 days since Jan 1, 1970
    if [[ $date_change -eq 14120 ]]; then
        #chage command to set warning and password expiration for $user
done < /etc/shadow
share|improve this answer
Of course, echo in the if first, you don't want to mess up system accounts... – Kyle Brandt Oct 9 '09 at 13:42
See Dennis' answer for a snippet that doesn't use awk, but uses shell arrays instead. – Kyle Brandt Oct 13 '09 at 14:09

To expire the password set the expiration date to a date in the past:

chage -E 0 username    # 0 is January 1, 1970; 14496 is 9/9/9

To remove the expiration use -1:

chage -E -1 username

Combine these with Kyle's script.

However, you can get your user and date_change using only one call to awk:

# Bash
read user date_change <<< $(echo $line | awk -F: '{print $1, $3}')


# Bash
read user date_change < <(echo $line | awk -F: '{print $1, $3}')


# Bourne
read user date_change <<EOF
`echo $line | awk -F: '{print $1, $3}'`

However, awk is unnecessary:

while IFS=: read -a line
    # Have they changed their password since I told them to on Jul 1?
    if [[ $date_change <= 14426 ]]; then
        # Expire their password, that'll get their attention
        chage -E 0 $user
done < /etc/shadow
share|improve this answer

The date the password was last changed is listed in /etc/shadow in the third field (coded as days since 1970/01/01).

You could then use the chage utiliy to enforce a password change after n days since the last change. But beware that this setting is persistent, it will expire the password every n days, so if you don't want that you will have to reset this in a second run, after the first change.

I really would like an option to enforce a password change upon first login, like MacOS and Windows offers.

share|improve this answer
3rd field I think... – Kyle Brandt Oct 9 '09 at 13:33
Yep, you are right, first one is username, not the password. – Sven Oct 9 '09 at 13:44

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.