#!perl

# Will be Scan ALL Users and CHECK PasswordExpirationTime
# If This time <= 6 days - will be send Notify to the User
# with informations:
# When PasswordExpirationTime
# How many Days befor Expiration
# How many loginGraceRemaing

#use MIME::Lite;
use Net::LDAP;
use Net::LDAP::LDIF;
use File::Path qw(rmtree);
use File::Basename qw(basename);
use Time::Local;
use Net::SMTP;

#use Date::Parse;


$HOST = '<ip-adress LDAP server>';
$PORT = 389;
$SSL_PORT = 636;
$PASSWD   = '<password LDAP query user>';

$BASEDN   = "ou=users,o=novell";

$ADMIN= "<LDAP quary user>";
# usera.company mast have rights READ and WRITE PassowordExpirationTime,
#  loginGraceLimit, loginGraceRemaining

# before 5 days to End begin Notify
# if need before 6 days change to:
# 60*60*24*6
my $TimeDif = 60*60*24*5;

my $TimeNow;
my $TimeTmp;
my $TimeExp;
my $T0 = 0;
my $MailTmp;
my $DnTmp;
my $lgl;
my $lgr;
$entry;

my $latm;

# Where the logs live.
$log_dir="sys:\system";

# Exit if the log directory's not there.
die "Log folder $log_dir does not exist" if (not -d $log_dir);

# The overall log file. Indicidual job logs will have incremental numbers
$log_file="$log_dir//pwdntfy.log";


mylog (" Begin", $log_file);

$TimeNow = time();

$searchstring="(&(objectclass=user)(cn=*))";
$attnames=["mail","passwordExpirationTime","dn","loginGraceLimit","loginGraceRemaining"];

#connect to the server
until($ldap = Net::LDAP->new($HOST, port => $PORT)) {
  die "Can not connect to ldap://$HOST:$PORT/" if ++$count > 10;
    sleep 1;
    }
    
    $r = $ldap->bind($ADMIN, password => $PASSWD, version=>3);
    die $r->error if $r->code;
    
    $r = $ldap->search(	base 	=> 	$BASEDN,
			scope	=>	'sub',
			filter 	=> 	$searchstring,
			attrs	=>	$attnames);
$MailTmp="empt";
$DnTmp="empt";
$TimeExp=0;
$TimeTmp=0;
$lgr=0;
$lgl=0;
foreach $entry ($r->entries){
	my @attrs = $entry->attributes;
	$MailTmp="empt";
	$DnTmp="empt";
	$TimeExp=0;
	$TimeTmp=0;
	foreach my $attr (@attrs) {
		my @value = $entry->get_value($attr);
		foreach my $value (@value){
			if ($attr eq "mail") {
			    $MailTmp = $value;
			}
			if  ( $attr eq "passwordExpirationTime" ) {
				$TimeExp1 = substr($value,0,14);
				$TimeExp = to1970(substr($value,0,14));
		    		$TimeTmp = $TimeExp - $TimeNow;
			}
		} 
	}
	$DnTmp = $entry->dn;
	if ( $TimeExp >= 0 ) {
		if ( $MailTmp eq "empt") {
			;
		}
		else {
# if TimeExpt exist and user_email exist -> check logintimeexpire or now and how many days before
			checkevent($DnTmp,$MailTmp,$TimeExp1,$TimeTmp);
		}
	}
# add check GraceLogin and GraceRemaining
# if GraceRemaining <GraceLimit  -> send notify about to the user!

        $lgl = $entry->get_value('loginGraceLimit');
        $lgr = $entry->get_value('loginGraceRemaining');
	if ($lgl > 0 ) {
		if ( $MailTmp eq "empt") {
			;
		} else {
			if ($lgr < $lgl) {
				;
				send_mail_l($MailTmp,$lgr);
			};
		};
	};
#
	$MailTmp="empt";
	$DnTmp="empt";
	$TimeExp=0;
	$TimeTmp=0;
    }
undef($ldap);
mylog (" End", $log_file);
mylog (" \n", $log_file);
exit();



sub mylog {

   # log output to screen and (optionally) to file
   # $_[0] is the string to be logged, $_[1] is the logfile

   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime;

   $out=sprintf("%02d",$mday);
   $out.="/";
   $out.=sprintf("%02d",$mon+1);
   $out.="/";
   $out.=1900+$year;
   $out.=" ";
   $out.=sprintf("%02d",$hour);
   $out.=":";
   $out.=sprintf("%02d",$min);
   $out.=":";
   $out.=sprintf("%02d",$sec);
   $out.=" $_[0]";
   $out.="\n";
   print $out;
   if ($_[1]) {
      $LOGFILE=">>" . $_[1];
      open LOGFILE or die "Can't open log file $_[1]: $!";
      print LOGFILE $out;
      close LOGFILE;
      }
   }


sub to1970 {															
# Convert input string to the Number string from 1970
# input string in format YYYYMMDDHHMMSS
#print "\nRAVNO[".$_[0]."]\n";
    if ( substr($_[0],0,4) > 2010) { 
	return (01,01,01,1,1,2010) 
    }
    else {
	return (timelocal( substr($_[0],12,2),substr($_[0],10,2) ,substr($_[0],8,2),substr($_[0],6,2),substr($_[0],4,2)-1,substr($_[0],0,4)) );
    }
}


sub checkevent {
# $_[0] - DN
# $_[1] - eMAil
# $_[2] - TimeExpiration
# $_[3] - Delta
#	print "---->DN=".$_[0]."\n";
#	print "---->Mail=".$_[1]."\n";
#	print "---->TimeExpiration=".$_[2]."\n";
#	print "---->Delta=".$_[3]."\n";

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($_[2]);
$mon++;
$year += 1900;
$time_str = sprintf ("%.2ld/%.2ld/$year %.2ld:%.2ld:%.2ld",$mday,$mon,$hour,$min,$sec);
    if ( $_[1] eq "empt") {
	mylog ("Was EMPT Mail address for ($_[0])",$log_file);
    } else 
	{
	    if ( $_[3] <= 0 ) {
#		Time was expired
		;
		if ( $_[2] == 0 ) {
# Time was Expiraion, but ExpireTime 0 !!! This normal Do not doing anyaction
			;
		} 
	    } else {
#		Time Will be Expired
		;
		if ( $_[3] <= $TimeDif ) {
#			to expire < 6 days !! need send Attantion
		send_mail($_[1],$_[2]);
# string below for change timeexpire to the 07:00am
#  exmaple: 
# before function: 20050619185346
# after function: 200506040000  (in ukarine (Donetsk) this= 07:00am !
		$latm=substr($_[2],0,8)."040000Z";
		$r = $ldap->modify($entry->dn, replace => { passwordExpirationTime => $latm });
		die $r->error if $r->code;
		;
		} else {
#			to expire  > 6 day , no need any action
		;

		}
	    }
	}
	;
}



sub send_mail {
	# send mail to the specific address with attantion
	# $_[0] = e_mail Recipient
	# $_[1] = Date Expiration
	# $_[2] = How many days befor End
# $passadmin - e_mail FROM WHICH will bi send mail

$passadmin="yourname\@org.nl";

# XXX.XXX.XXX.XXX - IP address SMTP server
$smtp=Net::SMTP->new('<your SMTP server>');

$mail = "yourname\@org.nl";

$smtp->mail($passadmin);
my $t = $_[0];
my $t1;
#$t =~ s/\@/\\@/g;
$t =~ s/\@/\@/g;
$t1 = $t;
mylog ("Was Send Mail address to ($t), timeexpire=[$_[1]]",$log_file);
$smtp->to("$t");
$smtp->data();
#$smtp->datasend("Disposition-Notification-To: \ yourname\@org.nl \n");
$smtp->datasend("Priority: Urgent\n");
$smtp->datasend("From: yourname\@org.nl\n");
$smtp->datasend("To: $t\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-type: text/plain\; charset=Windows-1251\n");
$smtp->datasend("Content-Transfer-Encoding: 8bit");
$smtp->datasend("\n");
# bellow you can change Text-Attantion about - when will be Time Expiration
$smtp->datasend("Subject: Uw Novell inlog password verloop binnenkort !!!");
$smtp->datasend("\n");
$smtp->datasend("In verband met het beveiligingsbeleid dient U periodiek Uw wachtwoord te wijzigen. Dat moment is nu aangebroken. Het nieuwe wachtwoord moet uit minimaal 6 karakters bestaan en mag niet eerder gebruikt zijn.\n");
$smtp->datasend("\n");
$smtp->datasend("\n");
$smtp->datasend("Uw wachtwoord verloopt op:");
$smtp->datasend("\n");
$smtp->datasend("",substr($_[1],6,2));
$smtp->datasend("-",substr($_[1],4,2));
$smtp->datasend("-",substr($_[1],0,4));
$smtp->datasend(" om ",substr($_[1],8,2));
$smtp->datasend(":",substr($_[1],10,2));
$smtp->datasend(" uur\n");
$smtp->datasend("\n");
$smtp->datasend("\n");
$smtp->datasend("Met vriendelijke groet,\n");
$smtp->datasend("Afdeling Automatisering");
$smtp->dataend();
$smtp->dataend();
$smtp->quit;


}



sub send_mail_l {
	# send mail to the specific address with attantion
	# $_[0] = e_mail Recipient
	# $_[1] = loginGraceRemaining

$passadmin="yourname\@org.nl";

$smtp=Net::SMTP->new('<SMTP server>');

$mail = "yourname\@org.nl";

$smtp->mail($passadmin);
my $t = $_[0];
my $t1;
#$t =~ s/\@/\\@/g;
$t =~ s/\@/\@/g;
$t1 = $t;
mylog ("Was Send Mail address to ($t) about loginGraceRemaining=[$_[1]]",$log_file);
$smtp->to("$t");
$smtp->data();
$smtp->datasend("Priority: Urgent\n");

#$smtp->datasend("Disposition-Notification-To: \ yourname\@org.nl \n");
$smtp->datasend("From: yourname\@org.nl\n");

$smtp->datasend("To: $t\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-type: text/plain\; charset=Windows-1251\n");
$smtp->datasend("Content-Transfer-Encoding: 8bit");
$smtp->datasend("\n");
# bellow you can change Text-Attantion about - How many GraceRemaing
#
$smtp->datasend("Subject:Uw Novell inlog password is verlopen !!!");
$smtp->datasend("\n");
$smtp->datasend("U heeft eerdere meldingen dat uw wachtwoord gaat verlopen genegeerd.\n");
$smtp->datasend("\n");
$smtp->datasend("U heeft nog:");
$smtp->datasend(" $_[1] kans(en)");
$smtp->datasend(" om uw wachtwoord aan te passen, daarna kunt u niet meer inloggen.\n");
$smtp->datasend("\n");
$smtp->datasend("\n");
$smtp->datasend("Met vriendelijke groet,\n");
$smtp->datasend("Afdeling Automatisering");
$smtp->dataend();
$smtp->quit;
}
