password reset in shell script using passwd



Resetting Password is a tedious job of the sys admin’s or DBA’s while managing over 100’s of servers.
Automatic password reset could make your job easier , What if your OS password gets reset automatically before expiry & reaches to your mailbox ? yes this is what came in my mind before I started hunting for the
Question How to reset password using passwd command in shell script?

While executing passwd command it takes three input i.e. Old password , New Password , New Password (confirmation)
It would have been difficult to pass these inputs to passwd prompts whithin shell without “expect” command
read –p command asks value by prompting for manual input but expect prompts as well as accepts input values in one go

expect can be configured to send the requested input value to desired command

expect is present in Linux by default but need to install it in rest of the Unix environment 


Script: expect.sh

#!/usr/bin/expect
set pwd [lindex $argv 0]
set pwd1 [lindex $argv 1]
set pwd2 [lindex $argv 2]
spawn /usr/bin/passwd
sleep 5
expect "UNIX password:"
sleep 5
send "$pwd\r"
sleep 5
expect "New password:"
sleep 5
send "$pwd1\r"
sleep 5
expect "Retype new password:"
sleep 5
send "$pwd2\r"
sleep 5
expect eof exit


Explanation:
expect utility path should be defined at the start of the script as like other shells
pwd, pwd1,pwd2 are three arguments that are defined to process three inputs old , new , new passwords
$argv defines position of the values to be passed
spawn should be followed by a command to be executed , here passwd being used without any username specified as in linux passwd should be supplied with username only when root executes it else username is assumed to be current username
expect “” is nothing but the prompt that you will receive if you would have executed the command defined by spawn manually on command prompt
send will pass input values to input prompt
Sleep is embedded to add some delay before passing values to input prompt, it helps in avoiding errors


Working:

$ expect expect.sh MEta12#$ KKll12#$ KKll12#$
spawn /usr/bin/passwd
Changing password for user ora11g.
Changing password for ora11g.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

 

Possible errors: In case password supplied is incorrect or sleep time is less between the two inputs below error can be seen

$ expect expect.sh 4KRuOwfM12#$ MEta12#$ MEta12#$
spawn /usr/bin/passwd
Changing password for user ora11g.
Changing password for ora11g.
(current) UNIX password:
passwd: Authentication token manipulation error
send: spawn id exp4 not open
    while executing
"send "$pwd1\r""
    (file "expect.sh" line 14)


 Error because old password was incorrect



Automation:
Now moving one step ahead lets setup auto password reset in shell script

To identify individual user id below command can be used as “who am I” gives the initial user name & not the current/switched username. In non-linux it is necessary to pass username to passwd command

USR=`id | /usr/bin/cut -d" " -f1 | sed 's/^........//' | sed 's/)//g' `;
export USR
echo $USR


Script: pwd_reset.sh



$ cat pwd_reset.sh

#!/bin/bash
MAIL="testlab@abc.com"
set -x
PATH=$PATH:/usr/bin
export PATH
BASE=`pwd`; export BASE
echo $BASE
OLDPSWD=`cat $BASE/oldpswd.lst`; export OLDPSWD
echo $OLDPSWD
USR=`id | /usr/bin/cut -d" " -f1 | sed 's/^........//' | sed 's/)//g' `;
export USR
echo $USR
#PSWD=`head /dev/urandom | tr -dc 'a-zA-Z0-9~!@#$%^&*-_' | fold -w 12 | head -n 1`;
#export PSWD
PSWD=`openssl rand -base64 6`;
export PSWD
PSWDNEW=`echo -n "$PSWD"; echo "12#e0"`;
export PSWDNEW
echo $PSWDNEW > $BASE/oldpswd.lst
expect expect.sh $OLDPSWD $PSWDNEW $PSWDNEW
mailx -s "$ORACLE_SID `hostname` $USR $PSWDNEW" $MAIL < /dev/null
chmod 600 $BASE/oldpswd.lst

Explanation: 
Above script makes use of expect.sh to which three input password values being passed
Script generates the random password using
openssl rand -base64 6
Old password is preserved on successful password reset of previous run

So, three inputs being passed to expect.sh in the form of old , new , new passwords
Password gets reset & email is sent with new password, hostname and username to intended recipient
  

pwd_reset.sh can be scheduled in crontab to run every month once if password policy has been set to expire password every 30+ day

7 comments:

  1. Hi Ajay,

    Needs to know this is only for OS level and as a DBA if a user wants a pwd reset to be done in Database user level this cannot be used i guess... Please help how we can reset the user password in database level. Please reply back to pradeepuwill@gmail.com... thanks

    ReplyDelete
    Replies
    1. Hey prince , on DB level it would be more easy to reset password just pass this string as a password to alter user command in sqlplus session within the same script
      -Ajay

      Delete
  2. Hi Ajay,
    Very nice and informative post. Well done.

    Regards.
    -Shashi

    ReplyDelete
  3. hi all,
    could anyone explain how to change automatically relational connections in informatica by using unix script.
    pls post any idea to Id.
    praveenkumar.in4@gmail.com

    ReplyDelete
  4. expect, send and spwan commands are not working, what shoud i do? i am using linux centos 7

    #!/bin/sh

    set pwd [lindex $argv 0]
    set pwd1 [lindex $argv 1]
    set pwd2 [lindex $argv 2]
    spawn /usr/bin/passwd
    sleep 5
    expect "UNIX password:"
    sleep 5
    send "$pwd\r"
    sleep 5
    expect "New password:"
    sleep 5
    send "$pwd1\r"
    sleep 5
    expect "Retype new password:"
    sleep 5
    send "$pwd2\r"
    sleep 5
    expect eof exit

    want to change own user password using user login not roor.. plz help me

    ReplyDelete
    Replies
    1. Hello Nitin,

      expect package is not installed by default in many Linux platforms or removed during hardening. You may download the rpm explicitly and install using rpm -ivh or install using repository yum install expect or apm install expect.

      Regards,
      www.moreajays.com

      Delete