Link to home
Create AccountLog in
Avatar of tech78i
tech78iFlag for United States of America

asked on

AIX password expiration script

I need a script for AIX 6 that will tell me when specific user account passwords are going to expire and then send an email using sendmail to the administrator in charge. I don't know if a shell script or perl would be best? Does not really matter as long as it works.
Avatar of woolmilkporc
woolmilkporc
Flag of Germany image

This is for all userids:

#!/bin/ksh
logins -ao | awk -F: '{print $1,$6,$7}' |while read user days when
  do
    if [[ $days -ge 0 ]] ; then
         printf "%12s: Password expires in %3s days on %12s\n" $user $days $when
    fi
   done |mailx -s "Account Expiration on $(hostname)" admin@domain.tld


Should you want to check just for specific users create a list "userlist" containing their names (one per line) and change the script like this:

#!/bin/ksh
while read entry
do
 logins -ao -l $entry | awk -F: '{print $1,$6,$7}' |while read user days when
   do
     if [[ $days -ge 0 ]] ; then
          printf "%12s: Password expires in %3s days on %12s\n" $user $days $when
     fi
    done
done < userlist |mailx -s "Account Expiration on $(hostname)" admin@domain.tld
Avatar of tech78i

ASKER

The email message sends but there is nothing on the message body. How about specify days like expiring 2 weeks from now.
Avatar of tech78i

ASKER

I need a report to show headers like the following below:

User         DaysLeft  Expires                   LastChanged               DaysValid
tony romo      4            Tue Nov 13       Tue Sept 13                      91

Thank you!
Avatar of tech78i

ASKER

I found this script and it does what I need except i would like the option to specify users inside the script or feed a it a file line per line. I also need it to email out as well. Thank you!

#!/usr/bin/perl
use strict;
use POSIX qw(ceil);
use User::pwent;
use Term::ANSIColor;

my ($user,%userids);

while ($user = getpwent()){
        my $u = $user->name;
        if ( `lsuser -a account_locked $u` =~ /.*account_locked=true.*/) {next;}

        chomp(my $lastupdate = `lssec -f /etc/security/passwd -a lastupdate -s $u | awk -F= '{print \$2}'`);
        if (! $lastupdate) { next; } 

        chomp(my $maxage = `lsuser -a maxage $u | awk -F= '{print \$2}'` * 7);

        my $expires = $lastupdate + (60 * 60 * 24 * $maxage);
        my $expire_date = scalar(localtime($expires));
        my $change_date = scalar(localtime($lastupdate));
        my $now = time();
        my $daysremaining = ceil((($expires - $now) / (60*60*24)) - 1);

        push(@{$userids{$u}}, $daysremaining,$maxage,$change_date,$expire_date);
}

print "User         DaysLeft  Expires                   LastChanged               DaysValid\n";

foreach $user (sort {$userids{$a}[0] <=> $userids{$b}[0] } keys %userids){
        if (@{$userids{$user}}[0] <= 0) {
                print color("red");
        }elsif(@{$userids{$user}}[0] <= 14){
                print color("yellow");
        }else{
                print color ("green");
        }

        printf "%-12s %-9d %-26s", $user, @{$userids{$user}}[0], @{$userids{$user}}[3];
        printf "%-25s %-9d\n", @{$userids{$user}}[2], @{$userids{$user}}[1];
        print color ("reset");
}

Open in new window

How should I have guessed which kind of headers you desire?

You didn't tell anything about report layout in your Q.

And sorry, I don't work on foreign scripts, if at all possible.

Good luck

wmp
Avatar of tech78i

ASKER

I was just brainstorming options for output of the data that's all. Thanks for your time,

Tech78i
On the mailing front, simply PIPE the output through mailx (assuming your sysadmin has configure sendmail) e.g

./perlScritName.pl  | mailx -s 'Output from AIX Password script'  someUser@some.domain

Open in new window


If you want to limit the script to a single username, use $ARGV[0] e.g.
#!/usr/bin/perl
use strict;
use POSIX qw(ceil);
use User::pwent;
use Term::ANSIColor;

my ($user,%userids);
my ($daysremaining,$maxage,$change_date,$expire_date);

#If a single user has been passed on the command line, report for that user, else go throuh the password file
if ($ARGV[0]) {
        ($daysremaining,$maxage,$change_date,$expire_date) = getUsrAttrib($ARGV[0]);
        push(@{$userids{$ARGV[0]}},$daysremaining,$maxage,$change_date,$expire_date)  if ($daysremaining);
} else {
  while ($user = getpwent()){
        ($daysremaining,$maxage,$change_date,$expire_date) = getUsrAttrib($user->name);
        push(@{$userids{$user->name}}, $daysremaining,$maxage,$change_date,$expire_date)  if ($daysremaining);
  }
}

print "User         DaysLeft  Expires                   LastChanged               DaysValid\n";

foreach $user (sort {$userids{$a}[0] <=> $userids{$b}[0] } keys %userids){
        if (@{$userids{$user}}[0] <= 0) {
                print color("red");
        }elsif(@{$userids{$user}}[0] <= 14){
                print color("yellow");
        }else{
                print color ("green");
        }

        printf "%-12s %-9d %-26s", $user, @{$userids{$user}}[0], @{$userids{$user}}[3];
        printf "%-25s %-9d\n", @{$userids{$user}}[2], @{$userids{$user}}[1];
        print color ("reset");
}

sub getUsrAttrib($) {
        my $u = $1;
        if ( `lsuser -a account_locked $u` =~ /.*account_locked=true.*/) {return;}

        chomp(my $lastupdate = `lssec -f /etc/security/passwd -a lastupdate -s $u | awk -F= '{print \$2}'`);

        if (! $lastupdate) { return; }

        chomp(my $maxage = `lsuser -a maxage $u | awk -F= '{print \$2}'` * 7);

        my $expires = $lastupdate + (60 * 60 * 24 * $maxage);
        my $expire_date = scalar(localtime($expires));
        my $change_date = scalar(localtime($lastupdate));
        my $now = time();
        my $now = time();
        my $daysremaining = ceil((($expires - $now) / (60*60*24)) - 1);

        return $daysremaining,$maxage,$change_date,$expire_date;
}

Open in new window

Avatar of tech78i

ASKER

How would you do the mailx part within the script itself? Thank you,

Tech78i
Messily as it isn't a shell script, it's a Perl script, far simpler / more flexible to use the line above.
ASKER CERTIFIED SOLUTION
Avatar of tech78i
tech78i
Flag of United States of America image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of tech78i

ASKER

I was able to find and modify a perl script for my organizations use. The suggestions given by the experts were not adequate for the task at hand.