I want to say thanks to John F Wall, Kalyan Manchikanti, Aaron Lineberger, C. G. Sellers, Brad_Morrison, Crist J. Clark and Rob Thompson, for the great answers and quick response. They had some excellent ideas, I knew someone already had this figured out. Thanks it has helped me a lot. Below are there e-mails =============================================================== Hi, I use PHP at the command line to do lots of these types of things, it has a great function for dealing w/ UNIX Epoch time (seconds since Jan 1st, 1970) as well as an easy mail() function. <? // Current Time $now = time(); // Time in the password file as $passexpire $difference = $now - $passexpire; // Now you have the number of seconds ($difference) between now and the expiration.. you // can easily fill the code to divide by this into hours, seconds, whatever.. ?> -Rob =============================================================== Kathy, Here are some ksh functions which might help. # Define the functions we will use. function isLeap { # isLeap(Year) if (( ((($1 % 4) == 0) && (($1 % 100) != 0)) || ((($1 % 400) == 0) && ( ($1 % 4000) != 0)) )) then return 0 else return 1 fi } function dayOfYear { # dayOfYear (Month, Day, Year) integer Count integer Day integer Month integer Year integer TotalDays Month=$1 Day=$2 Year=$3 set -A DaysInMonth 0 31 28 31 30 31 30 31 31 30 31 30 31 if isLeap ${Year} then DaysInMonth[2]=29 fi Count=1 TotalDays=0 while (( Count < Month )) do (( TotalDays += DaysInMonth[$Count] )) (( Count += 1 )) done (( TotalDays += Day )) print "${TotalDays}" return } function daysSinceEpoch { # daysSinceEpoch (Month, Day, Year) integer Count integer Day integer Month integer Year integer DSE integer numLeaps Month=$1 Day=$2 Year=$3 (( DSE = (Year - 1970) * 365 - 1 )) # DSE for 1/1/1970 is 0. Count=1970 numLeaps=0 while (( Count < Year )) do if isLeap ${Count} then (( numLeaps += 1 )) fi (( Count += 1 )) done (( DSE += numLeaps )) (( DSE += $(dayOfYear ${Month} ${Day} ${Year}) )) print "${DSE}" return } John =============================================================== Kathy, And here is an nawk script which processes the output of the "passwd -sa" command as you theorized. #!/usr/bin/nawk -f BEGIN { FMT1 = "%-12s\t%-9s\t%-10s\t%s.\n" FMT2 = "%-12s\t%-9s\t%-10s\t" "date '+%m %d %Y'" | getline ThisMonth = $1 + 0 ThisDay = $2 + 0 ThisYear = $3 + 0 Today = daysSinceEpoc(ThisMonth, ThisDay, ThisYear) } $4 == "LK" { printf FMT1, $1, $2, $3, "Password is locked" } $4 == "NP" { printf FMT1, $1, $2, $3, "NO PASSWORD" } $4 == "PS" { Host = $1 Category = $2 UserID = $3 LastDate = $5 if ( length(LastDate) == 0 ) { printf FMT2, Host, "CustApp", UserID printf "NON-EXPIRING PASSWORD.\n" next } DaysValid = $7 split(LastDate, MDY, "/") MDY[1] += 0 MDY[2] += 0 if (MDY[3] < 70) MDY[3] += 2000 else MDY[3] += 1900 PasswordReset = daysSinceEpoc(MDY[1], MDY[2], MDY[3]) PasswordValid = PasswordReset + DaysValid DaysToExpire = PasswordValid - Today printf FMT2, Host, Category, UserID Plural="s" if (DaysToExpire == 1) Plural="" if (DaysToExpire > 0) printf "Password expires in %d day%s.\n", DaysToExpire, Plural else printf "ALREADY EXPIRED.\n" } function isLeap(Year) { return (((Year % 4) == 0) && ((Year % 100) != 0)) || (((Year % 400) == 0) && ((Year % 4000) !=0)) } function daysSinceEpoc(Month, Day, Year) { # Compute number of days since 1/1/1970. DSE = (Year - 1970) * 365 - 1 # DSE for 1/1/1970 is 0. numLeaps = 0 for (i=1970; i<Year; i++) if (isLeap(i)) numLeaps++ DSE += numLeaps DSE += dayOfYear(Month, Day, Year) return (DSE) } function dayOfYear(Month, Day, Year) { # Compute the day of the year for this date. TotalDays = 0 DaysInMonth[1] = 31 DaysInMonth[2] = 28 DaysInMonth[3] = 31 DaysInMonth[4] = 30 DaysInMonth[5] = 31 DaysInMonth[6] = 30 DaysInMonth[7] = 31 DaysInMonth[8] = 31 DaysInMonth[9] = 30 DaysInMonth[10] = 31 DaysInMonth[11] = 30 DaysInMonth[12] = 31 if (isLeap(Year)) DaysInMonth[2] = 29 for (i=1; i<Month; i++) { TotalDays += DaysInMonth[i] } TotalDays += Day return (TotalDays) } John =============================================================== Attached are two scripts that will help you in what you want to do. You will have to tweak them to suit your environment. Remember that passwd_expiry.ksh script needs the second script epoch.pl to exist. It's better if you keep them in the same directory. Also include your email addresses in the ADMINS variable.. hth, Kalyan Manchikanti =============================================================== This isn't exactly what you asked for but it is something similar that I did on an AIX box. It basically calculates time in seconds since the last password change and if that time is greater than 9 (5443200) or 12 (7257600) weeks it tells you. This should be easily modifiable to place in cron and change the execution of echo to mail. AIX doesn't use an /etc/shadow file explicitly (/etc/security/passwd), but you should be able to modify the for loop to look at the /etc/shadow file as opposed to the /etc/passwd file. If I had time I'd port it for you, but I'm kind of swamped and what fun would that be for you? ;) Questions, let me know. #!/usr/bin/ksh if [[ `whoami` != root ]] then print "You must be root to run this script." exit fi USRCHG=`perl -e "use Time::Local; print time-5443200;"` ADMCHG=`perl -e "use Time::Local; print time-7257600;"` DATE=`perl -e "use Time::Local; print time;"` USRDAT=`perl -e "use Time::Local; print scalar localtime(time-5443200);"` ADMDAT=`perl -e "use Time::Local; print scalar localtime(time-7257600);"` if [ "$1" = "" ] then for user in `cat /etc/passwd | egrep -v "^root:|^daemon:|^bin:|^sys:|^adm:|^uucp:|^nobo dy:|^lpd:|^invscout:|^imnadm:|^nuucp:|^ipsec:|^kmem:" | awk -F: '{print $1}'` do grep -p lastupdate /etc/security/passwd | grep -p ^$user: > /dev/null if [ $? -eq 0 ] then LAST=`pwdadm -q $user | grep last | awk '{print $3}'` LSTDAT=`perl -e "use Time::Local; print scalar localtime($LAST);"` if (( $LAST < $USRCHG )) then if (( $LAST < $ADMCHG )) then echo "$user: \tRequires Admin To Change." echo "Last Change:\t$LSTDAT" echo "12 Weeks: \t$ADMDAT\n" else echo "$user: \tRequires User To Change." echo "Last Change:\t$LSTDAT" echo "9 Weeks: \t$USRDAT\n" fi else echo "$user: \tNo Change Required." echo "Last Change:\t$LSTDAT\n" fi else echo "$user: \tDoes not have a \"lastupdate\" entry!\n" fi done else user="$1" grep -p lastupdate /etc/security/passwd | grep -p ^$user: > /dev/null if [ $? -eq 0 ] then LAST=`pwdadm -q $user | grep last | awk '{print $3}'` LSTDAT=`perl -e "use Time::Local; print scalar localtime($LAST);"` if (( $LAST < $USRCHG )) then if (( $LAST < $ADMCHG )) then echo "$user: \tRequires Admin To Change." echo "Last Change:\t$LSTDAT" echo "12 Weeks: \t$ADMDAT\n" else echo "$user: \tRequires User To Change." echo "Last Change:\t$LSTDAT" echo "9 Weeks: \t$USRDAT\n" fi else echo "$user: \tNo Change Required." echo "Last Change:\t$LSTDAT\n" fi else echo "$user: \tDoes not have a \"lastupdate\" entry!\n" fi fi Aaron Lineberger =============================================================== epoch to local should do it for example, perl has a good way to do this :::::::::::::: epoch2local.pl :::::::::::::: #!/usr/bin/perl # # $1 = epoch time in format of shadowExpireA $input = $ARGV[0]; $e = ($input*24*60*60); print scalar localtime ($e) ; print "\n\n "; Google converting epoch to local time and you will get more help... Sellers =============================================================== You have the right idea, what you need is a tool that provides a library for conversion to/from UNIX "epoch time". I don't think any of the shells will do it. Perl might, and it's probably already on your system. You may need to get/install a date conversion library. I'm surprised that there's no built-in mechanism to notify users. Brad Morrison - CONBRAM =============================================================== It's probably easier to get the UNIX epoch time, seconds since January 1, 1970, which is what the computer counts internally anyway, and convert that to days. An easy Perl script, open(SHADOW, '/etc/shadow') || die("failed to open /etc/shadow\n"); $today = time() / 86400; # Today's date. while (<SHADOW>) { @pw = split(/:/); $lastchg = $pw[2]; # Date of last change. $max = $pw[4]; # Expiration timer. $warn = $pw[5]; # Warning period. # Calculate days until expiration. $expire = $max - ($today - $lastchg); # Check if we are in the warning period. If so, mail user. if ($expire < $warn) { # Insert code for message to user here. } # If less than three days, warn the administrator. if ($expire < 3) { # Insert code for message to admin here. } } -- Crist J. Clark Below is my original question =============================================================== I feel like this is probably an easy question, so I have been searching the internet for an answer, but just can t figure this out myself. My question simply stated is, I want to be able to e-mail a person outside of the unix server, when a unix id is about to expire. Also if the password will expire within 3 days I want to e-mail the system administrator. Yes if the user is logged on the person will see the warning message, but some IDs aren't logged on daily In the /etc/shadow file the 3rd field is the number of days (since January 1, 1970) since the password was last changed. I am looking for a way to take today date and display as the number of days since January 1, 1970 and then compare to two numbers. If the numbers are within the password warning time frame then send the appropriate e-mail Another thought was to use the date from passwd s where the date is displayed as mm/dd/yy, convert to a Julian date do the calculations then convert back to gregorian corn: root: #passwd -s rnott rnott PS 07/27/05 7 63 7 I am on Sun Solaris 9, Kathy Ange Virginia Department of Agriculture & Consumer Services Information Systems (804) 371-5793 Voice Mail (804) 371-5282 FAX Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com #!/bin/ksh #Author:Kalyan Manchikanti #C:Date:02/08/2005 #Check the Shadow table for the epoch value and warn the users of password expiry #This script needs the epoch.pl script to exist ID=`/usr/bin/id | /usr/bin/cut -d" " -f1` if [[ "${ID}" != "uid=0(root)" ]] then echo "You should run as root" exit 1 fi SHADOW=/etc/shadow #Location of the epoch.pl script. Change it to wherever you are going to keep the epoch.pl script.. ESCPT=/home/kmanchi/bin/epoch.pl HOSTNAME=`hostname` #Email addresses of the admins / users needing the notification #ADMINS="" for i in `cat $SHADOW` do LGN=`echo $i |awk -F: '{print \$1}'` MAXDAYS=`echo $i | awk -F: '{print \$5}'` echo "$MAXDAYS" EPOCH=`echo $i |awk -F: '{print \$3}'` EVAL=`$ESCPT $EPOCH | awk '{print \$2}'` #echo "$EVAL" if [[ $EVAL == `expr $MAXDAYS - 7` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in a week. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 6` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 6 days. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 5` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 5 days. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 4` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 4 days. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 3` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 3 days. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 2` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 2 days. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == `expr $MAXDAYS - 1` ]] then echo "Password for unix user $LGN on `hostname` is going to expire in 1 day. Please change it ASAP" | mailx -s 'password expiry' $ADMINS elif [[ $EVAL == "$MAXDAYS" ]] then echo "PASSWORD FOR USER $LGN HAS EXPIRED.PLEASE CHANGE IT ASAP TO AVOID JOBS FAILING" fi done #!/bin/perl -w use integer; if ($#ARGV != 0) { print "Usage: epoch.pl <number>\n"; exit 1; } $input_day=$ARGV[0]; if ($input_day =~ /(\D+)/) { print "ERROR: Please enter a number!!!\n"; exit 1; } $clktime=time; $curr_day=$clktime/86400; $diff=$curr_day - $input_day; if ($diff < 0) { $diff=-1*$diff; print "$input_day: $diff days from current day\n"; } else { print "$input_day: $diff days to current day\n"; } _______________________________________________ sunmanagers mailing list sunmanagers@sunmanagers.org http://www.sunmanagers.org/mailman/listinfo/sunmanagersReceived on Thu Aug 4 15:40:27 2005
This archive was generated by hypermail 2.1.8 : Thu Mar 03 2016 - 06:43:50 EST