Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Nice to meet you.

I have used the chage command in Linux to set the password expiration date for a user.

When the expiration date approaches, I want to notify the user automatically.

This is how I imagine it should happen:

  1. check daily to determine if the password is about to expire
  2. If the password has more than 11 days left, do nothing
  3. If the password has 10 or fewer days left, send a notification email to the user

Do I need to write a script to accomplish the above? Or is there an automatic way to accomplish this?

Thanks

share|improve this question
    
+1 and Brent gets an award for being a good egg and helping ffffff clean up the wording a little ;-) –  username May 25 '09 at 6:43
    
Aye. Well done Brent :) –  squillman May 26 '09 at 23:57

3 Answers 3

up vote 2 down vote accepted

See if this does what you're looking for. You can set the warning time using the chage command or passwd -w:

#!/bin/bash

# notifypwexp - send mail to users whose passwords are expiring soon
# designed to be run daily or weekly from cron

# call with -w for weekly mode (checks to see if warning period begins in the next 7 days
# use -w for a weekly cron job, avoiding excessive emails

# with no option, it only checks whether we're in the warning period now
# use this for a daily cron job

# by Dennis Williamson

# ### SETUP ###

if [[ $1 == "-w" ]] # check for expiration warnings beginning during the next seven days
then
    weekmode=7
else
    weekmode=0
fi

admins="root postmaster"
declare -r aged=21 # minimum days after expiration before admins are emailed, set to 0 for "always"

hostname=$(hostname --fqdn)

# /etc/shadow is system dependent
shadowfile="/etc/shadow"
# fields in /etc/shadow
declare -r last=2
#declare -r may=3 # not used in this script
declare -r must=4
declare -r warn=5
#declare -r grace=6 # not used in this script
declare -r disable=7

declare -r doesntmust=99999
declare -r warndefault=7

passwdfile="/etc/passwd"
declare -r uidfield=3
declare -r unamefield=1
# UID range is system dependent
declare -r uidmin=1000
declare -r uidmax=65534 # exclusive

# remove the hardcoded path from these progs to use them via $PATH
# mailx is system dependent
notifyprog="/bin/mailx"
grepprog="/bin/grep"
awkprog="/usr/bin/awk"
dateprog="/bin/date"

# comment out one of these
#useUTC=""
useUTC="-u"

# +%s is a GNUism - set it to blank and use dateformat if you have
# a system that uses something else like epochdays, for example
epochseconds="+%s"
dateformat=""   # blank for GNU when epochseconds="+%s"
secondsperday=86400 # set this to 1 for no division

today=$(($($dateprog $useUTC $epochseconds $dateformat)/$secondsperday))
oIFS=$IFS

# ### END SETUP ###

# ### MAIL TEMPLATES ###

# use single quotes around templates, backslash escapes and substitutions 
# will be evaluated upon output
usersubjecttemplate='Your password is expiring soon'
userbodytemplate='Your password on $hostname expires in $(($expdate - $today)) days.

Please contact the IT department by email at \"helpdesk\" or at 
extension 555 if you have any questions. Help is also available at 
http://helpdesk.example.com/password'

adminsubjecttemplate='User Password Expired: $user@$hostname'
adminbodytemplate='The password for user $user on $hostname expired $age days ago.

Please contact this user about their inactive account and consider whether
the account should be disabled or deleted.'

# ### END MAIL TEMPLATES ###

# get real users
users=$($awkprog -F:    -v uidfield=$uidfield \
    		-v unamefield=$unamefield \
    		-v uidmin=$uidmin \
    		-v uidmax=$uidmax \
    		-- '$uidfield>=uidmin && $uidfield<uidmax \
    			{print $unamefield}' $passwdfile)

for user in $users;
do

    IFS=":"
    usershadow=$($grepprog ^$user $shadowfile)

    # make an array out of it
    usershadow=($usershadow)
    IFS=$oIFS

    mustchange=${usershadow[$must]}
    disabledate=${usershadow[$disable]:-$doesntmust}

    # skip users that aren't expiring or that are disabled
    if [[ $mustchange -ge $doesntmust || $disabledate -le $today  ]] ; then continue; fi;

    lastchange=${usershadow[$last]}
    warndays=${usershadow[$warn]:-$warndefault}
    expdate=$(($lastchange + $mustchange))

    threshhold=$(($today + $warndays + $weekmode))

    if [[ $expdate -lt $threshhold ]];
    then
        if [[ $expdate -ge $today ]];
        then
            subject=$(eval "echo \"$usersubjecttemplate\"")
            body=$(eval "echo \"$userbodytemplate\"")
            echo -e "$body" | $notifyprog -s "$subject" $user 
        else
            if [[ $age -ge $aged ]];
            then
                subject=$(eval "echo \"$adminsubjecttemplate\"")
                body=$(eval "echo \"$adminbodytemplate\"")
                echo -e "$body" | $notifyprog -s "$subject" $admins
            fi
        fi
    fi

done
share|improve this answer

Bash Script + Cron Seems like the most obvious solution.

share|improve this answer
    
Nice!, but I 'm bash begginer ... Would you take me a example codes? –  freddiefujiwra May 25 '09 at 3:48

Use the -w option when changing their passwords. -w This will set the number of days in advance the user will begin receiving warnings that her password will expire, if the user’s account supports password lifetimes. Available to root only.

share|improve this answer
    
Thanks' Can I notify users for emails? –  freddiefujiwra May 25 '09 at 8:49

Your Answer

 
discard

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.