Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

time_last_unsuccessful_login 2

Status
Not open for further replies.

teqmem

Programmer
Nov 26, 2004
114
0
0
US
Hello,

How do you easily convert or display /etc/security/lastlog values so they are humanly readable?

For example,
time_last_unsuccessful_login = 1139603175

Thanks.
 
use this in your script:
perl -we "print scalar localtime 1139495251" this converts to Thu Feb 9 09:27:31 2006
 
Hi Please help,

I am also looking for a similar script, i have no experience of scripting whatsoever.
so the scenario is :

I need a script which will look at all the ids on a box and check time_last_login , if its more than 30 days i need to lock the account, if more than 60 days i need to remove the account..

please help

Thankyou
 
This is quite a major project for a scripting novice. A starting point is to look at the output of
Code:
lsuser -c -a time_last_login ALL
You now have five posible scenarios
[ol]
[li]You don't want to delete the users under any circumastances (root for example)[/li]
[li]The user has never logged in - you don't specify what happens under these circumstances[/li]
[li]The user has logged in within the last 30 days[/li]
[li]The user falls withing the 30 - 60 day period[/li]
[li]The user exceeds the 60 day period[/li]
[/ol]
But now you hit the problem. lsuser returns the time in seconds since the epoch. ksh is not very good at dealing with this. plamb and I now reach for perl which comes free with AIX and has some rather good time functions. However I'm not sure that I have the time to write the script for you. Writing this yourself as a perl script might be a good learning exercise assuming you can persuade your boss to give you the time.

Columb Healy
 
Thanx for you help so far...

i still need help, can anyone else help

thankyou
 
I have a perl script you're welcome to use.

Code:
#!/usr/bin/perl
#*********************************************************************
#
#	Name:		DormantUsers.
#
#	Function:	Lists all users who have not logged in since a
#			specified time.
#
#	Usage:		DormantUsers [ -h ] | [ -v ] | [ -d <days> ] [ -p ]
#
#	Created by:	
#
#	Amendments:
#		1).	Add switch -x to send the output to an Excel spreadsheet.
#		2).	Replace the 'more' command with the 'less' command on data
#			output.
#
#	Released:
#		v1.0 - 01/11/2004.
#		v1.1 - 06/12/2004.
#		v1.2 - 18/01/2005.
#
#*********************************************************************

use warnings;
use strict;
use Getopt::Std;
use Spreadsheet::WriteExcel;
sub verify_usage; 
sub usage_error;
sub get_user_attributes; 
sub print_user_attributes;
sub save_user_attributes2excel;
sub set_up_page_hdrs ($);
sub set_up_col_hdrs ($$);
sub set_up_col_formats ($$);
sub format_user_attributes ($);

#
#	Declare and initialise all global variables.
#
our $version = "1.2";
our $basename = $0;
$basename =~ s<.*/><>; 					### Store the program base name ###
$/ = "";						### Input Record Delimiter set to
							###	blank line ###
$= = 23;						### No. of lines per screen display ###
our $dormant_days = 90;
our $now = time; 					### Store today's date and time ###
our %user_attr = ();
###our $output_command = "more -cdluv";	### Default: screen display ###
my $less_prompt = "?e(END) .[Press f to scroll forward, b to scroll back, ";
$less_prompt .= "q to quit]\\:";
our $output_command = "less -CeFr~ -P'$less_prompt'";
our $output2excel = 0;					### Boolean flag ###
our $excel_dir = "/samba/data/Excel";

#
#	Main process.	
#
{
verify_usage();
get_user_attributes();
unless ( $output2excel ) {
	print_user_attributes();
	}
else {
	save_user_attributes2excel();
	}
exit;
}

sub verify_usage() {
#*********************************************************************
#
#	Check program flags and arguments.
#
#*********************************************************************
#
#	Process program options.
#
	my %option = ();
	getopts ("d:hpxv", \%option) or usage_error;
	usage_error if ( $ARGV [0] );
	usage_error if ( defined $option {h} );
	die ("$basename: Version $version\n") if ( defined $option {v} );

#
#	Process "-d" option, if present.
#
	if ( defined $option {d} ) {
		usage_error unless ( $option {d} =~ /^\d+$/ );
		( $dormant_days = $option {d} ) =~ s/^0+//;
	}

#
#	Ensure only 1 of options "-p" and "-x" are present.
#
	usage_error if ( defined $option {p} ) and ( defined $option {x} );

#
#	Process "-p" option, if present.
#
	if ( defined $option {p} ) {
		$= = 61;						### No. of lines per printed page ### 
		$output_command = "lp -s -dauprt02";
	}

#
#	Process "-x" option, if present.
#
	if ( defined $option {x} ) {
		$output2excel = 1;
	}

} ### End of sub.

sub usage_error {
#*********************************************************************
#
#	Display usage error and exit.
#
#*********************************************************************
	die <<EOF;

Usage:
$basename [ -d <days> ] [ -p | -x ]
$basename -h
$basename -v

Switches
========
-d <days>	Lists users who have not logged in within the last <days>,
		default = 90.
-p		Sends the output to the default printer.
-x		Sends the output to an Excel spreadsheet,
		($excel_dir/$basename.xls).
-h		Displays this message and exits.
-v		Displays the program version and exits.

EOF
} ### End of sub.

sub get_user_attributes() {
#*********************************************************************
#
#	Get and store all required user account attributes for users who
#	have either never logged in or last logged in before a certain
#	date.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#
	my $first_uid = 202;
	my $threshold = $now - ( 24 * 60 * 60 * $dormant_days );
	my $lsuser_command = "lsuser -f ALL";
	my $login_name = "";
	my @attr_list = ();
	my $attr_key = "";
	my $attr_value = "";

#
#	Run the 'lsuser' command with 'sudo' provided the program is not
#	being run by the root user.	
#
	$lsuser_command = "sudo " . $lsuser_command unless ( $< == 0 );

#
#	open input pipe to 'lsuser' command.
#
	open (USERLIST, "-|", $lsuser_command)
		or die ("$basename: cannot open pipe to '$lsuser_command' - $!\n");

#
#	Process each list of user attributes from the 'lsuser' command.
#
	LIST:
	while ( <USERLIST> ) {
		
#
#	Ignore user attributes if the 'uid' is before the
#	predefined first 'uid' or the 'time_last_login' is 
#	within the threshold.
#
		next LIST if ( /id=-?(\d+)/ ) and ( $1 < $first_uid );
		next LIST if ( /time_last_login=(\d+)/ ) and ( $1 >= $threshold );
	
#
#	Remove any tabs from the input.
#
		tr /\t//d;
		
#
#	Split input into login name and list of attributes.
#
		($login_name, @attr_list) = split /\n/;
		$login_name = substr ($login_name, 0, -1);

#
#	Store each user attribute.
#
		foreach ( @attr_list ) {
			($attr_key, $attr_value) = split /=/;
			$user_attr {$login_name} -> {$attr_key} = $attr_value;
		} ### End of foreach loop.
	
	} ### End of while loop.

#
#	close pipe to 'lsuser' command.
#
	close USERLIST
		or die ("$basename: error closing pipe to '$lsuser_command' - $!\n");

} ### End of sub.

sub print_user_attributes() {
#*********************************************************************
#
#	Sort and print dormant user account attributes.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#
	my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
	my @date_time = ();
	my $run_time = "";
	my $run_date = "";
	my $line_no = 0;
	my $login_name = "";
	my $uid = "";
	my $user_name = "";
	my $last_login_date = "";
	my $acc_locked = "";

#
#	Declare output formats.
#
format STDOUT_TOP =
                                 @<<<<<<<<<<<<                        @>>>>>>>
"DORMANT USERS", "Page $%"

As at @<<<< on @<<<<<<<<<<                           @>>>>>>>>>>>>>>>>>>>>>>>>
$run_time, $run_date, "Prior to $dormant_days days ago"

 No.   Login       UID   User Name              Last Login   Locked
 ===   =====       ===   =========              ==========   ======
.

format STDOUT =
@>>>   @<<<<<<<   @>>>   @<<<<<<<<<<<<<<<<<<<   @|||||||||     @||
$line_no . ".", $login_name, $uid, $user_name, $last_login_date, $acc_locked
.

#
#	open output pipe to required output command.
#
	open (STDOUT, "|-", $output_command)
		or die ("$basename: cannot open pipe to '$output_command' - $!\n");

#
#	Format the run date and time.
#
	@date_time = localtime ($now);
	$run_time = sprintf ("%02d", $date_time [2]) . ":";
	$run_time .= sprintf ("%02d", $date_time [1]);
	$run_date = sprintf ("%02d", $date_time [3]) . " ";
	$run_date .= $month [$date_time [4]] . " ";
	$run_date .= ($date_time [5] + 1900);
	
#
#	Process each set of user attributes.
#
	foreach ( sort keys %user_attr ) {
		$line_no++;
		$login_name = $_;
		($uid, $user_name, $last_login_date, $acc_locked) =
			format_user_attributes ($user_attr {$login_name});
#
#	Display user attributes line.
#
		write;
	
	} ### End of for loop.

#
#	close pipe to output command.
#
	close STDOUT
		or die ("$basename: error closing pipe to '$output_command' - $!\n");

} ### End of sub.

sub	save_user_attributes2excel() {
#*********************************************************************
#
#	Sort and save the dormant user account attributes in an Excel
#	spreadsheet.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#
	my $row = 0;
	my $login_name = "";
	my $attr_list = {};
	my $uid = "";
	my $user_name = "";
	my $last_login_date = "";
	my $acc_locked = "";

#
#	Set the umask for the Excel workbook.
#
	umask (0111);

#
#	Create the Excel workbook.
#
	my $workbook = Spreadsheet::WriteExcel -> new ("$excel_dir/$basename.xls");
	die ("$basename: Error creating Excel workbook '$excel_dir/$basename' - $!\n")
		unless defined $workbook;

#
#	Add a worksheet to the Excel workbook.
#
	my $worksheet = $workbook -> add_worksheet();

#
#	Set up page and column headers and column formats.
#
	set_up_page_hdrs ($worksheet);
	set_up_col_hdrs ($workbook, $worksheet);
	set_up_col_formats ($workbook, $worksheet);

#
#	Process each set of user attributes.
#
	foreach ( sort keys %user_attr ) {
		$row++;
		$login_name = $_;
		($uid, $user_name, $last_login_date, $acc_locked) =
			format_user_attributes ($user_attr {$login_name});

#
#	Add a new row to the worksheet.
#
		$worksheet -> write ($row, 0, $login_name);
		$worksheet -> write ($row, 1, $uid);
		$worksheet -> write ($row, 2, $user_name);
		$worksheet -> write ($row, 3, $last_login_date);
		if ( $acc_locked eq "Yes" ) {
			$acc_locked = chr (252);
		}
		else {
			$acc_locked = chr (251);
		}
		$worksheet -> write ($row, 4, $acc_locked);

	} ### End of for loop.

#
#	Close the Excel workbook.
#
	$workbook -> close()
		or (die "$basename: Error closing Excel workbook '$excel_dir/$basename' - $!\n");

} ### End of sub.

sub set_up_page_hdrs ($) {
#*********************************************************************
#
#	Set up the page headers for the current worksheet.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#
	my $worksheet = {};
	my $header_line = "";
	my $footer_line = "";
	my @date_time = ();
	my $run_date = "";
	my $run_time = "";

#
#	Store parameter input.
#
	$worksheet = shift;

#
#	Format the run date and time.
#
	@date_time = localtime ($now);
	$run_date = sprintf ("%02d", $date_time [3]) . "/";
	$run_date .= sprintf ("%02d", $date_time [4]) . "/";
	$run_date .= ($date_time [5] + 1900);
	$run_time = sprintf ("%02d", $date_time [2]) . ":";
	$run_time .= sprintf ("%02d", $date_time [1]);

#
#	Define the page format for the worksheet.
#	
	$worksheet -> center_horizontally();
	$worksheet -> set_margins_LR (0.5);
	$header_line = '&L&14&"Arial, Bold"DORMANT USERS';
	$header_line .= '&R&14';
	$header_line .= "Prior to $dormant_days days ago";
	$worksheet -> set_header ($header_line);
	$footer_line = '&L&10&"Arial"';
	$footer_line .= "Run date: $run_date @ $run_time";
	$footer_line .= '&R&10&"Arial"Page &P of &N';
	$worksheet -> set_footer ($footer_line);
	$worksheet -> repeat_rows(0);

} ### End of sub.

sub set_up_col_hdrs ($$) {
#*********************************************************************
#
#	Set up the column headers in the first row of the current
#	worksheet within the current workbook.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#	
	my $workbook = {};
	my $worksheet = {};

#
#	Store parameter input.
#
	$workbook = shift;
	$worksheet = shift;

#
#	Define the format for the column headers.
#
	my $colhdr_format = $workbook -> add_format();
	$colhdr_format -> set_bold (1);
	$colhdr_format -> set_italic (1);
	$colhdr_format -> set_align ('center');
	$colhdr_format -> set_text_wrap (1);

#
#	Add the column headers row to the current worksheet,
#
	$worksheet -> write (0, 0, "Login Name", $colhdr_format);
	$worksheet -> write (0, 1, "UID", $colhdr_format);
	$worksheet -> write (0, 2, "User Name", $colhdr_format);
	$worksheet -> write (0, 3, "Last Login Date", $colhdr_format);
	$worksheet -> write (0, 4, "Account Locked", $colhdr_format);

} ### End of sub.

sub set_up_col_formats ($$) {
#*********************************************************************
#
#	Set up the formats for each relevant column of the current 
#	worksheet within the current workbook.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#	
	my $workbook = {};
	my $worksheet = {};

#
#	Store parameter input.
#
	$workbook = shift;
	$worksheet = shift;

#
#	Define and set the format for column A.
#
	my $col_A_format = $workbook -> add_format();
	$col_A_format -> set_font ('Courier New');
	$col_A_format -> set_align ('center');
	$worksheet -> set_column (0, 0, 10, $col_A_format);

#
#	Define and set the format for column B.
#
	my $col_B_format = $workbook -> add_format();
	$col_B_format -> set_align ('center');
	$worksheet -> set_column (1, 1, 8, $col_B_format);

#
#	Define and set the format for column C.
#
	my $col_C_format = $workbook -> add_format();
	$col_C_format -> set_italic (1);
	$worksheet -> set_column (2, 2, 20, $col_C_format);

#
#	Define and set the format for column D.
#
	my $col_D_format = $workbook -> add_format();
	$col_D_format -> set_align ('center');
	$worksheet -> set_column (3, 3, 12, $col_D_format);

#
#	Define and set the format for column E.
#
	my $col_E_format = $workbook -> add_format();
	$col_E_format -> set_font ('Wingdings');
	$col_E_format -> set_align ('center');
	$worksheet -> set_column (4, 4, 8, $col_E_format);

} ### End of sub.

sub format_user_attributes($) {
#*********************************************************************
#
#	Format attributes for a single user.
#
#*********************************************************************
#
#	Declare and initialise local variables.
#
	my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
	my $attr_list = {};
	my $uid = "";
	my $user_name = "";
	my @date_time = ();
	my $last_login_date = "";
	my $acc_locked = "";

#
#	Store parameter input.
#
	$attr_list = shift;

#
#	Get user id.
#
	$uid = $attr_list -> {"id"};

#
#	Get user's real name.
#
	if ( exists $attr_list -> {"gecos"} ) {
		$user_name = $attr_list -> {"gecos"};
	}
	else {
		$user_name = "N/A";
	}

#
#	Get last login date.
#
	if ( exists $attr_list -> {"time_last_login"} ) {
		@date_time = localtime ($attr_list -> {"time_last_login"});
		$last_login_date = sprintf ("%02d", $date_time [3]);
		$last_login_date .= "/";
		$last_login_date .= sprintf ("%02d", ($date_time [4] + 1));
		$last_login_date .= "/";
		$last_login_date .= ($date_time [5] + 1900);
	}
	else {
		$last_login_date = "Never";
	}

#
#	Get account locked status.
#
	if ( exists $attr_list -> {"account_locked"} ) {
		if ( $attr_list -> {"account_locked"} eq "true" ) {
			$acc_locked = "Yes";
		}
		else {
			$acc_locked = "No";
		}
	}	

#
#	Return the user attributes.
#
	return ($uid, $user_name, $last_login_date, $acc_locked);

} ### End of sub.

### End of program.

Note that the script also uses 'sudo' to allow non-root users to run the script.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top