#!/usr/local/bin/perl -w
use strict;
#
my $program = 'nag';
# nag - script to be run once a day, every day, by root, to remind users via 
# e-mail to renew their passwords before they expire.
# Frank A. Brunotts (bruno005)

# Load necessary modules.
use Date::Manip;
use Net::LDAP;

# Logging
my $timestamp = &UnixDate('today',"%d/%b/%Y:%H:%M:%S");
my $logdir = "/var/log/$program";
mkdir $logdir if [ !(-d $logdir) ];
my $logdate = &UnixDate('today',"%Y%m");
my $logfile = "$logdate.$program.log";
my $log = "$logdir/$logfile";
open (LOG, ">>$log");
print LOG "$timestamp start\n";

# Define environment-specific variables.
my $host = `hostname`;
chomp $host;
my $hostphrase = $host;
$hostphrase = 'cww.census.gov (a.k.a. develop.ssd.census.gov)' if $host eq 'develop';
$hostphrase = 'webdev.ssd.census.gov' if $host eq 'webdev.ssd.census.gov';
$hostphrase = 'stage.census.gov (a.k.a. web1stage.ssd.census.gov)' if $host eq 'web1stage.ssd.census.gov';
$hostphrase = 'www.census.gov' if $host eq 'blueprod';
$hostphrase = 'ftp2.census.gov' if $host eq 'backup03.csvd.census.gov';

# Determine which LDAP server to use.
my $ldapserver;
my $fullName;
my $internal = `grep 148.129.127.22 /etc/resolv.conf`;
if ($internal) { 
  $ldapserver = 'ldap.tco.census.gov';
  $fullName = 'fullName';
  } else {
  $ldapserver = 'ldap-e.census.gov';
  $fullName = 'cn';
}
my $ldap = Net::LDAP->new($ldapserver);

# Which OS?
my $systype = `uname`;
chomp $systype;

# Read the shadow file.
my @shadow;
open SHADOW, '/etc/shadow';
  while (<SHADOW>) {
  push (@shadow, $_);
  }
close SHADOW;

# Structure of shadow database:
# username:password:lastchg:min:max:warn:inactive:expire:flag
# Evaluate each row.
my $row = shift(@shadow);
chomp($row);

# Identify users.
my @users;
while (@shadow) {
# user accounts are 8 characters, first 2 are lower-case alpha, last 3 are numeric,
# middle 3 characters may be either
  if ($row =~ /^[a-z][a-z]([a-z]|[0-9])([a-z]|[0-9])([a-z]|[0-9])[0-9][0-9][0-9]:.*$/) {
# If third character is numeric, the fourth and fifth must be numeric.
    if ($row =~ /^..[0-9][0-9][0-9]...:.*$/) {
      push (@users, $row);
# If fourth character is numeric, the fifth must be numeric.
    } elsif ($row =~ /^..[a-z][0-9][0-9]...:.*$/) {
      push (@users, $row);
# If first four characters are alpha, fifth character can be alpha or numeric.
    } elsif ($row =~ /^..[a-z][a-z]([a-z]|[0-9])...:.*$/) {
      push (@users, $row);
    }
  }
  $row = shift(@shadow);
  chomp($row);
}

# Identify active users.
# If the last field is not empty, ignore this user. 
# This is a way to exclude those who do not wish to receive notifications.
$row = shift(@users);
my @active_users;
if ($systype eq 'Linux') {
  while (@users) {
    if ($row =~ /^.*:..................................:.*:.*:.*:.*:.*:.*:$/) {
      push (@active_users, $row);
    }
  $row = shift(@users);
  }
} else {
  while (@users) {
    if ($row =~ /^.*:.............:.*:.*:.*:.*:.*:.*:$/) {
      push (@active_users, $row);
    }
  $row = shift(@users);
  }
}

my $today = (int(time()/86400));
my ($username, $lastchg, $max,$daysleft);
$row = shift(@active_users);
while (@active_users) {
  $username = $row;
  $username =~ s/^(........).*/$1/;
  $lastchg = $row;
  $lastchg =~ s/^.*:.*:(.*):.*:.*:.*:.*:.*:.*$/$1/;
  $lastchg = $today if (length($lastchg) == 0);
  $max = $row;
  $max =~ s/^.*:.*:.*:.*:(.*):.*:.*:.*:.*$/$1/;
  $max = 99999 if (length($max) == 0);
  $lastchg = ($today - $max) if ($lastchg == 0);
  my $age = $today - $lastchg;
  $daysleft = $max - $age;
# print "$username\n" if (($daysleft == 28)||($daysleft == 14)||($daysleft == 7)||($daysleft == 1)||($daysleft == 0));
   &nag if (($daysleft == 28)||($daysleft == 14)||($daysleft == 7)||($daysleft == 1)||($daysleft == 0));
  $row = shift(@active_users);
}

sub nag {
my $ldapmsg = $ldap->search(
  base   => "o=U.S. Census Bureau,c=US",
  filter => "uid=$username"
  );
my $inldap = $ldapmsg->count;
if ( $inldap) {
  my $cn = 'Hello';
  $cn = $ldapmsg->entry->get_value($fullName) if (length ($ldapmsg->entry->get_value($fullName)) > 0);
  my $to = 'frank.a.brunotts@census.gov';
  $to = $ldapmsg->entry->get_value('mail') if (length($ldapmsg->entry->get_value('mail')) > 0);
  my ($expirephrase, $expiredate);
  $expiredate = DateCalc("today","+ $daysleft days");
  my $expiredatephrase = &UnixDate("$expiredate","(%A, %B %e, %Y)");
  if ($daysleft == 0) {
    $expirephrase = 'has expired';
    $expiredatephrase = '';
  } elsif ($daysleft == 1) {
    $expirephrase = "is due to expire tomorrow";
  } else {
    $expirephrase = "is due to expire in $daysleft days";
  }
  my $subject = "your $username account password on $hostphrase $expirephrase";
  open (MAIL, "|/usr/lib/sendmail -t");

print MAIL "To: $to\n";
print MAIL "Reply-to: \"The Web Site Services & Coordination Staff\" <SSD.Internet.Staff\@census.gov>\n";
print MAIL "From: ${program} <${program}\@$host>\n";
#print MAIL "Bcc: ssd.internet.staff\@census.gov\n" if ($daysleft == 0);
#print MAIL "Bcc: frank.a.brunotts\@census.gov\n" if ($daysleft == 0);
#print MAIL "Bcc: frank.a.brunotts\@census.gov\n";
print MAIL "Subject: $subject\n";
print MAIL "MIME-Version: 1.0\n";
print MAIL "Content-type: text/html; charset=US-ASCII\n\n\n";
print MAIL "<a href=http://www.census.gov/>";
print MAIL "<img src=http://www.census.gov/main/www/img/cb_head.gif width=639 height=25 border=0 alt='U\.S. Census Bureau' /></a>\n";
print MAIL "<p><b>$cn:</b><br><br>\n";
print MAIL "Your <i>$username</i> account password on <b>$hostphrase</b> $expirephrase $expiredatephrase.\n";
print MAIL "<p>Please renew your password.  To renew your password, you will need to log in to $hostphrase using Secure Shell (SSH). \n";

my $shell = `grep "^$username:" /etc/passwd | cut -d: -f7`;
chomp($shell);

if ($shell eq '/bin/passwd') {
print MAIL "You will automatically be prompted to renew your password when you log in.\n";
} elsif ($daysleft == 0) {
print MAIL "Since your account $expirephrase, you will automatically be prompted to renew your password when you log in. \n";
} else {
print MAIL "Once logged in, run the <code>passwd</code> command and follow the prompts.\n";
}

print MAIL "<p><h3>Questions??</h3>\n";
print MAIL "<p>If you have questions about any of this, please reply to this message or see the FAQs below.\n";
print MAIL "<p>Thank you for your cooperation.\n";
print MAIL "<p><b>The Web Site Services & Coordination Staff</b>\n";
print MAIL "<p><hr>\n";
print MAIL "<p><h3>Frequently Asked Questions</h3>\n";
print MAIL "<p><b>Why must I change my password?</b>\n";
print MAIL "<p>In accordance with the &quot;<a href=http://cww2.census.gov/it/itso/docs/BOCPasswordPolicy.doc>Information Technology Computer Password Management Policy</a>&quot;, passwords must be changed every 90 days.\n";
print MAIL "<p><b>I've forgotten my password. What do I do?</b>\n";
print MAIL "<p>You will need to have CSvD issue you a temporary password before you may continue. Call the Customer help Center at 301-763-3333 and open a REMEDY ticket. If the support analyst that takes your call requests a \"CTI,\" it is Accounts/CSVD-SSD/RESET PASSWORD.\n";
print MAIL "<p><b>What is &quot;secure shell&quot;?</b>\n";
print MAIL "<p>&quot;Secure shell&quot; (or ssh) is, like telnet, a program  for  logging  into  a  remote machine and executing commands. It is more secure than telnet because network communications are encrypted.\n";
print MAIL "<p><b>How do I run ssh?</b>\n";
print MAIL "<p>&quot;Secure shell&quot; (or ssh) is available on most UNIX systems. There are also Windows versions available.\n";
print MAIL "<p><b>How do I get a Windows version of ssh?</b>\n";
print MAIL "<p>You may already have a Windows version of ssh available to you. It's called \"SSH Secure Shell.\" Check your &quot;Novell-delivered Applications&quot; group. If it's not there, ask the Customer Help Center (301-763-3333) to make it available. Once made available, follow the directions below.\n";
print MAIL "<p><hr>\n";
print MAIL "<h3>Installation and Setup Instructions for </h3><h1>SSH Secure Shell</h1>\n";
print MAIL "<p>The Customer Help Center (CHC) of the Lan Technology Support Office (LTSO), will make \"SSH Secure Shell\" available to you in your \"Novell-delivered Applications\" group if it is not already there. Call the CHC at 301-763-3333 if necessary. Once the application icon is visible, install \"SSH Secure Shell\" by right-clicking on the icon and choosing \"Verify.\"</p>\n";
print MAIL "<center><img src=http://webdev.ssd.census.gov/nag-img/nda.gif width=512 height=372 alt='sample image of a Novell-delivered Applications window with the SSH Secure Shell application icon highlighted' \></center>\n";
print MAIL "<p>A window like the one below will display while the application is installed.</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/distribute.gif width=366  height=195 alt=\"sample image of window displayed while SSH Secure Shell application is installed\"></p></center>\n";
print MAIL "<p>The application will automatically start once installation is complete. Once started, a window similar to the one displayed below will appear.</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/default.gif width=596 height=496 alt=\"sample image of the window that appears when the SSH Secure Shell application is started\"></p></center>\n";
print MAIL "<p>To log in, click on the \"Quick Connect\" button. A window similar to the one below will appear. Fill in the appropriate values for \"Host Name\" ($hostphrase) and \"User Name\" ($username) and then click the \"Connect\" button.</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/connect.gif width=398  height=145 alt=\"sample image of window displayed after clicking the Connect button in the SSH Secure Shell application\"></p></center>\n";
print MAIL "<p>If this is your first time connecting to the host from this installation of \"SSH Secure Shell,\" a window similar to the one below will appear. Click the \"Yes\" button.</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/hostid.gif width=435 height=223 alt=\"sample image of window displayed if this is your first time connecting to the host from this installation of SSH Secure Shell\"></p></center>\n";
print MAIL "<p>Once a connection to the server is established, a message window similar to the one below will appear. Click \"OK.\"</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/message.gif width=574  height=392 alt=\"sample image of message window that appears once a connection is established in SSH Secure Shell\"></p></center>\n";
print MAIL "<p>Enter your current password when prompted.</p>\n";
print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/password.gif width=381 height=88 alt=\"sample image of password prompt window from SSH Secure Shell\"></p></center>\n";
print MAIL "<p>";

if ($shell eq '/bin/passwd') {
  print MAIL "Since you are logging in to $hostphrase, you will automatically be prompted to renew your password when you log in.\n";
  print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/session-auto-passwd.gif width=597  height=498 alt=\"sample image of a Secure Shell session where the user is automatically prompted to change the password\"></p></center>\n";
} elsif ($daysleft == 0) {
  print MAIL "Since your account $expirephrase, you will automatically be prompted to renew your password when you log in. \n";
  print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/session-auto-passwd.gif width=597  height=498 alt=\"sample image of a Secure Shell session where the user is automatically prompted to change the password\"></p></center>\n";
} else {
  print MAIL "Once logged in, run the <code>passwd</code> command and follow the prompts.\n";
  print MAIL "<center><p><img src=http://webdev.ssd.census.gov/nag-img/session-manual-passwd.gif width=597  height=498 alt=\"sample image of a Secure Shell session where the user must run the passwd command in order to change the password\"></p></center>\n";
}

print MAIL "\n\n" ;
close(MAIL);

  $timestamp = &UnixDate('today',"%d/%b/%Y:%H:%M:%S");
  print LOG "$timestamp $username $daysleft\n";
  }
}

$timestamp = &UnixDate('today',"%d/%b/%Y:%H:%M:%S");
print LOG "$timestamp stop\n\n";
close (LOG);
