# Summary - Date conversion script

From: Kathy Ange <kathyange_at_yahoo.com>
Date: Thu Aug 04 2005 - 15:39:57 EDT
```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.

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
next
}
DaysValid = \$7

split(LastDate, MDY, "/")

MDY[1] += 0
MDY[2] += 0
if (MDY[3] < 70)
MDY[3] += 2000
else
MDY[3] += 1900

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
}

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

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
\$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"
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"
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.

===============================================================
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,

\$today = time() / 86400; # Today's date.
@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

#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`

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/sunmanagers
```
Received 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