Link to home
Start Free TrialLog in
Avatar of bevege
bevegeFlag for United States of America

asked on

Bash script to notify users that password is about to expire

I need some help creating a scrip to email users that their password is going to expire in 7 days.  I have been able to get a file with username, passwordlastchanged time and email address all on one line. For example:

fred 20090101 fred@test.com
john 20090102 john@test.com
chris 20090103 chris@test.com
and so on

I now need a bash/awk script that will read each line one by one and if the password is greater than or equal to 83 days (90 days -7 for warning,,) send the user a email.  If it is less than 83 days don't send the user a email.

We're running Centos 5.2.  The reason for this is that some of our users never log into unix boxes so they don't know that their password is about to expire.  Other users that DO log into linux boxes have no problems because they are notified on the command line.  BTW, I forgot to mention that we are using LDAP for authentication of both linux boxes and some network devices.

I need this ASAP, I tried but could not figure it out all the way.  I'm very new to bash scripting.  Any help would be greatly appreciated.

BE
Avatar of Julian Parker
Julian Parker
Flag of United Kingdom of Great Britain and Northern Ireland image

can you post what you have so far...
ASKER CERTIFIED SOLUTION
Avatar of Hugh Fraser
Hugh Fraser
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
well this is quite easy, i will provide you a higher level overview to design this script:

1. Get a counter variable to store the password changed last time value for each user
2. define a variable that will have store the hard limit of 83 days from the present day for a user
3. store the diff value in another variable
4. Now use the if else to check the 83 days value and if its going beyond that then initiate the warning function to user mailing list.
4. get this logic working for one user, and then put a if else again to get this working for each user.

Let me know if any issues..
Avatar of bevege

ASKER

Thank you all so much for responding.  I used hfraser's link to do some better searching and found several ideas.  Would have helped if I had done a better job of searching google in the first place but live and learn.

Here's what I came up with after modifying another script I found.  Please comment if you find any errors or better ways to do this.  I'm just learning so I needed a simple script that I could understand exactly what it was doing.

I've commented out the original lines that I changed.  I believe this script was originally written for a Sun box.  I could not get the original mail piece to work so I just changed it to use the standard mailx.

There are a few things that seem unnecessary to me such as the mail functions.  Couldn't this just be done on the same line as the if then statement?  

Also, not sure why we would need the password variable (passwd)

I don't believe I need the shadow fields for $8, $9, $10 and $11.

let me know what you guys think.  I'm going to tinker around with this a little more to test some of the things I just mentioned but it DOES work as is.

Thanks again



#!/bin/sh 
 
#rsj 01/16/2003 
#this script is intended to be ran from a cron job. 
#It will email user warnings when their passwd is getting 
#close to expiration. 
 
#Function to email users if password is expired.  We may or may not want to use this.  Will discuss.
mail_msg_expire() 
{
echo $mailexpire_body | mail -s "$mailexpire_subj" $name@test.com 
} 
 
#Function to email users if password is less than the warning period. 
mail_msg_warn() 
{
echo $mailwarn_body | mail -s "$mailwarn_subj $expire days" $name@test.com
} 
 
#Days since epoch time.  Probably want to change this to "date --date 'today' +%s"/86400 so it will work on a
#Box that doesn't have perl installed.
 
NDAYS=`/usr/bin/perl -e 'printf("%d\n", time / (3600 * 24))'` 
echo NDAYS = $NDAYS 
 
#FQDN for email because shadow only has username.  This assumes email address is username@test.com.
#If we need to add different FQDN's we can pull the emails directly from ldap in the future.
fqdn=test.com
 
#Message to be sent back to user
mailexpire_subj=" Warning your passwd has expired"
mailexpire_body=" Please SSH into testserver.test.com to change your password "
mailwarn_subj=" Warning, Your password will expire in:"
mailwarn_body=" Please SSH into testserver.test.com to update your password "
 
for user in `getent shadow | awk -F: '{printf("%s:%s:%s:%s:%s:%s\n", $1, $2, $3, $4, $5, $6, $8, $9, $10, $11)}'` 
do 
        #echo user = $user 
        name=`echo $user | cut -d: -f1` 
        passwd=`echo $user | cut -d: -f2` 
        lastchg=`echo $user | cut -d: -f3` 
        min=`echo $user | cut -d: -f4` 
        max=`echo $user | cut -d: -f5` 
        warn=`echo $user | cut -d: -f6` 
        if [ "$max" != -1 -a "$passwd" != "*LK*" ]; then 
                if [ "$max" = "" ]; then 
                        echo "invalid value of max for $name" 
                        max=-1 
                fi 
                if [ "$lastchg" = "" ]; then 
                        echo "invalid value of lastchg for $name" 
                        lastchg=0 
                fi 
                #echo info = $name:$lastchg:$min:$max:$warn:$delta 
                delta=`expr $NDAYS - $lastchg` 
                expire=`expr $max - $delta` 
                if [ $expire -le 0 ]; then 
                        echo info = $name:$lastchg:$min:$max:$warn:$delta 
                        echo " Warning your passwd has expired" 
                        mail_msg_expire $name "Your passwd has expired" 
                elif [ $expire -le $warn ]; then 
                        echo info = $name:$lastchg:$min:$max:$warn:$delta 
                        echo " Warning passwd will expire in $expire days" 
                        mail_msg_warn $name "Warning your passwd expires in $expire days" 
                fi 
        fi 
        #else 
                #echo no expire for $name:$lastchg:$min:$max:$warn 
        #fi 
done 

Open in new window

Avatar of bevege

ASKER

I just noticed that I copied the script without the original information commented out.  Here is the old version with original information just commented out.

#!/bin/sh 
 
 
#rsj 01/16/2003 
#this script is intended to be ran from a cron job. 
#It will email user warnings when their passwd is getting 
#close to expiration. 
 
 
#mail_msg() 
#{ 
#        mail $1 << EOF 
#Subject: $2 
#From: sysadmin 
#$1 $2 
#EOF 
#} 
 
mail_msg_expire() 
{
echo $mailexpire | mail -s "$mailexpire" $name@bevege.com 
} 
 
mail_msg_warn() 
{
echo $mailwarn | mail -s "$mailwarn"  $name@bevege.com
} 
 
 
#Days since epoch time
NDAYS=`/usr/bin/perl -e 'printf("%d\n", time / (3600 * 24))'` 
echo NDAYS = $NDAYS 
 
fqdn=contournetworks.net
mailexpire=" Warning your passwd has expired"
mailwarn=" Warning passwd will expire in $expire days"
 
#for user in `niscat -M passwd.org_dir | awk -F: '{printf("%s:%s:%s:%s:%s:%s\n", $1, $2, $8, $9, $10, $11)}'` 
for user in `getent shadow | awk -F: '{printf("%s:%s:%s:%s:%s:%s\n", $1, $2, $3, $4, $5, $6, $8, $9, $10, $11)}'` 
do 
        #echo user = $user 
        name=`echo $user | cut -d: -f1` 
        passwd=`echo $user | cut -d: -f2` 
        lastchg=`echo $user | cut -d: -f3` 
        min=`echo $user | cut -d: -f4` 
        max=`echo $user | cut -d: -f5` 
        warn=`echo $user | cut -d: -f6` 
        if [ "$max" != -1 -a "$passwd" != "*LK*" ]; then 
                if [ "$max" = "" ]; then 
                        echo "invalid value of max for $name" 
                        max=-1 
                fi 
                if [ "$lastchg" = "" ]; then 
                        echo "invalid value of lastchg for $name" 
                        lastchg=0 
                fi 
                #echo info = $name:$lastchg:$min:$max:$warn:$delta 
                delta=`expr $NDAYS - $lastchg` 
                expire=`expr $max - $delta` 
                if [ $expire -le 0 ]; then 
                        echo info = $name:$lastchg:$min:$max:$warn:$delta 
                        echo " Warning your passwd has expired" 
                        mail_msg_expire $name "Your passwd has expired" 
                elif [ $expire -le $warn ]; then 
                        echo info = $name:$lastchg:$min:$max:$warn:$delta 
                        echo " Warning passwd will expire in $expire days" 
                        mail_msg_warn $name "Warning your passwd expires in $expire days" 
                fi 
        fi 
        #else 
                #echo no expire for $name:$lastchg:$min:$max:$warn 
        #fi 
done 

Open in new window