http://www.perlmonks.org?node_id=887631

Where I work, we have a whole bunch of people that share a couple of service accounts that need to be used occasionally. I don't like that for security reasons, but it is unavoidable right now. The problem I keep having is that hey consistently lock the account because they cannot remember the password, but then don't tell anyone. Later on someone who does know the password needs to get in, but cannot. They just need the failed logon count reset, and the account unlocked. I am lazy. I don't like having to open smitty, and go through all the keystrokes to reset these things. I also don't like remembering and typing the long commands to do this at the command line. Here is my solution.

#!/usr/bin/perl =pod =head1 NAME resetuserlogon.pl =head1 SYNOPSIS perl resetuserlogon.pl <servername> <username> =head1 DESCRIPTION This script will check and then reset the invalid logon count and unlo +ck the users account. =head1 AUTHOR TechFly Version: 1.0 Date: 2-9-2011 =cut use warnings; use strict; use IO::Prompt; use Net::SSH::Expect; #Variable declarations if (@ARGV != 2) { print ("\nUseage: resetuserlogon.pl <servername> <username>\n"); print ("Please review your arguments.\n\n"); exit 1; } my $servername = $ARGV[0]; my $username = $ARGV[1]; #IO::Prompt uses ARGV to assign the input. You have to clear ARGV bef +ore you can use IO::Prompt. pop @ARGV; pop @ARGV; my $password = prompt "Please enter the root password for $servername: + ", -e => '*'; my $ssh = Net::SSH::Expect->new ( host=> $servername, password=> $password, user=> 'root', raw_pty=> 1 ); my $sshlogin = $ssh->login(); print("\nUnlocking user account: $username\n"); print("On server: $servername\n\n"); my $listsec = $ssh->exec("lssec -f /etc/security/lastlog -a \"unsucces +sful_login_count\" -s $username"); my $accountlocked = $ssh->exec("lsuser -a account_locked $username"); my @listsecsuccede = split(/=|\n/, $listsec); chomp($listsecsuccede[1]); if ($listsecsuccede[1] != 0) { print("The account has $listsecsuccede[1] unsuccessful logon attem +pts.\n"); if ($ssh->exec("chsec -f /etc/security/lastlog -a \"unsuccessful_l +ogin_count=0\" -s $username")) { print(" The unsuccessful logon count was reset.\n") } else { print("The unsuccessfull logon count was NOT reset\n"); } } else { print("The account $username does not have any unsuccessful logon +attempts.\n"); } my @listaccountlocked = split(/=|\n/, $accountlocked); if ($listaccountlocked[1] =~ /^true$/i) { print("The account is currently locked.\n"); $ssh->exec("chuser account_locked='false' $username"); if ($ssh->exec("lsuser -a account_locked $username")){ print(" The account was successfully unlocked.\n"); } else { print("The account was NOT successfully unlocked.\n"); } } else { print("The account $username is not locked.\n"); } print("\n\n"); $ssh->close();

A little code, and I don't have to do all the work of resetting these accounts any more. I don't see a lot of sysadmin type code out here, but that is about all you will see from me.

I am always receptive to a better way to do things, if anyone has suggestions. Thanks to wind, kennethk, roboticus, and hbm for suggestions while I was writing this, and for reminding me that I can indeed use at least a small amount of regex in my code. On a side note, I ordered the O'Reillys regex book after they pointed that out.

cheers

Replies are listed 'Best First'.
Re: AIX reset users
by Limbic~Region (Chancellor) on Feb 11, 2011 at 16:30 UTC
    TechFly,
    I have worked in a similar situation. The solution that I implemented was to change the service account to something no one knew and to have people sudo su - <user>. It took quite a while because there were a number of scripts that had the password hard coded (and in the clear) that needed to be addressed. It took some time and some comprimises needed to be made but the end result was satisfactory.

    My recommendation to you regarding your code is don't write scripts like this. You will end up copy/pasting all over the place. Instead, write modules that expose AIX admin commands in a consistent manner that can be re-used in script after script. Isn't the following more appealing:

    ... my $account = AIX::Account->new($user); if ($account->locked) { print "Attempting to unlock account for '$user'\n"; if (! $account->unlock) { print "Failed to unlock account for '$user': ", $account->last +_error; } else { print "Account for '$user' successfully unlocked\n"; } } else { print "Account for '$user' was not locked\n"; }

    Cheers - L~R

      For the su - <username>, that is set up. The problem lies in the human psyche. I have been at my current position for a short time, so cannot force change. The users don't want to use su, and the current admin does not want to go through the hassle of forcing them. it will change when I can force it, but for now, I will have to wait.

      As for your suggestion, it is a great one. It is actually something I was thinking about working on, but I am fairly new to perl, so have a bit more learning to do. That is on my list of things I wish to do though.

      Thanks for the great suggestion.

      sudo su - username seems like an overkill. Don't give the users root access via sudo if they don't need that, just give them access to that one service user, and let them use sudo -u username -i.

        ambrus,
        Giving them root access would be insane. Of course you would limit what commands could be issued via sudo by the configuration of the sudoers configuration. While there are shortcuts as you point out, the command I provided doesn't give someone root access.

        Cheers - L~R