Hi All,

I have a problem.

I need to write a shell script to change the password. The user may want to change his own password by this script.

He will have to provide the required 3 parameters i.e. old password, new password and retype new password as arguments in command line.

like, ./pass.sh old new new

How do I do it. I am in a fix. :(

I am not allowed to use expect etc.

Please help me.

Thanks.
Asimananda

i am using a shell script which changes the password of all the servers in the network and also of the host server (as per your requirement) but it uses except.

Earlier i had a perl script to change the password.

If you want i can give you both the scripts and you can modify them as per your requirement.

Amit

i am using a shell script which changes the password of all the servers in the network and also of the host server (as per your requirement) but it uses except.

Earlier i had a perl script to change the password.

If you want i can give you both the scripts and you can modify them as per your requirement.

Amit

Amit,

I would be very interested in your scripts. Would you mind sending them to me at . This sounds exactly what I am needing.
Thanks

PS

I have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

Attachments
#!/opt/sfw/bin/expect --

#########################################################################################
# ChangePassword.exp
#
#########################################################################################

proc ChangePassword {new_passwd} {

        expect {
                -re "New Password: |New password:" { send "$new_passwd\r" }
                timeout { return 1}
        }

        expect {
        -re "Re-enter new Password: |Re-enter new password:" { send "$new_passwd\r" }
        timeout { return 1}
        }

        expect {
                -re "\\$|#" {send "echo \$?\r"}
                eof {return}
        }

        expect {
                -re "\r\n(.*)\r\n" {set password_status $expect_out(1,string)}
        }

        if { $password_status != 0 } {
                error "passwd command failed"
        }
}

##########################################################################################
# MAIN
#
##########################################################################################

send_user "\n******************************************************************\n"
send_user "*                     Password Change Management                 *"
send_user "\n******************************************************************\n"
send_user "\n1)Change root password\n\n"
send_user "2)Change amit password \n\n"
send_user "q)Exit\n"
send_user "Your choice? "

set timeout -1
while {1} {
        expect_user {
                -re "1\n" {set user root; break}
                -re "2\n" {set user amit; break}
                -re "q\n" exit
                -re ".*\n" {send_user "\nYour choice? "}
        }
}

send_user "Your choice was: $user\n"

while {1} {
        send_user "\nPlease enter new $user password : "
        expect_user {
                -re "(.*)\n" {set new_password  $expect_out(1,string);send_user "\nPlease re-enter new $user password: "}
        }

        expect_user {
                -re "(.*)\n" {
                                if [ string match $new_password $expect_out(1,string)] {
                                        break
                                } else {
                                                send_user "\nPasswords don't match.\n"
                                }
                }
        }
}


set date_string [exec date "+20%y%m%d%H%M"]

log_file ChangePassword.$date_string.log

log_user 0

send_user "\n\nChanging $user password.\n\n"

spawn passwd $user

if [catch { ChangePassword $new_password } result ] {
        send_user "$result\n"
        exit
} else {
        send_user "\n\n***Successfully changed $user password.***\n\n"
}


}

I have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

Hi Amit,

Do you have a similar script (only ChangePasswd) in Perl? If you do can you please share it.

Thanks,
Vivek.

Hi Amit,

I am looking for a script just like yours: I have many servers and I need to change their root psw.
Could you post the entire script?
thanks a lot

Ezra

I have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

I have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

Hi Amit,

Im looking for the script which you have for changing password on multiple servers. Would you mind sending them to me at.

Thanks and regards,
VinodKumar

I have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

Hello Amit,

I am trying to get a perl script to communicate with the passwd program. I do not have access to the modules expect or IO::Pty. I also do not have access to the expect utility.

So far I have found a free pty/tty pair and opened them and set them to autoflush. Then I fork.

In the child I close stdin, stdout and stderr to reopen them associated to the new tty handle and exec passwd.

In the parent I want to read and write to the pty to interact with passwd. This is not working. The passwd direct access to the tty is not reaching my tty.

Maybe I need to set the controling tty in the child before doing the exec? How do I do that?

Cheers,
sut

Hi. This is what I've put together so far. Can somebody tell me what I am doing wrong? I've searched the web and read the manuals but I just can't see how to get the communication with passwd to go directly through the terminal. I think I need to make the newly opened tty the controling tty but apparently don't know how.

I am working on AIX 5.2 and am not allowed to install IO::Pty or expect. So I need to roll my own.

Thank you very much for any pointers.

Attachments
#!/usr/bin/perl -w

use strict;

use Fcntl;

use POSIX qw(setsid ttyname);

my $str;
my $bank;
my $unit;
my $s;
my $pid;
my $ptyname;
my $passwd = "/usr/bin/passwd";

sysopen( PTC, "/dev/ptc", O_RDWR | O_NOCTTY ) or die "Can't open a pseudo-terminal. $!";
$s = select(PTC); $| = 1; select($s);

$ptyname = ttyname(fileno(PTC));

print "Got " . $ptyname . "\n";

sysopen( PTS, $ptyname, O_RDWR | O_NOCTTY ) or die "Can't open a pseudo-terminal (PTS). l. $!";

close( PTC );
print "Closed PTC\n";

$pid = fork;
if ($pid < 0) {
 fprintf STDERR "Can't fork...\n";
 exit(1);
}

if ($pid == 0) { # I'm the son ; exec the program...
  setsid();
  setpgrp();
  close( PTS );
  close STDERR;
  open( STDERR, ">>pty.log" );
  sysopen( PTS, $ptyname, O_RDWR ) or die "Can't open a pseudo-terminal (child). l. $!";
  close STDIN;
  close STDOUT; 
  open(STDIN,"<&PTS");
  open(STDOUT,">&PTS");
  $| = 1;
  open( LOG, ">>pty.log" );
  # This does not exist on my system
  # $str = ioctl( PTS, TIOCSCTTY, 0 ) || -1;
  # print LOG "ioctl returned $str\n";
  exec $passwd;
  $str = "$!";
  open( LOG, ">>pty.log" ) && print LOG "Can't exec passwd $str\n";
  die "Cannot exec $passwd: $!";
  }

print "this pid: $$\n";
print "child pid: $pid\n";
print "sleep\n";
sleep 2;
print "get input\n";
while (<PTS>) {
    print "****" . $_ . "\n";
    if( /Old/ ) {
        $str = <>;
        print PTS;
    }
}

close( PTS );
print "Closed PTS\n";
exit 0;

Hi. It works now. The attached script works on SYS V type terminals and was tested on AIX 5.3. I will eventually get it working on Sun and Linux and will need to work out the Berkly style TTYs which involves a bit of code similar to:

found: {
  for $bank ('p'..'z') {
    for $unit (('0'..'9'),('a'..'f')) {
      # +> : access in read/write mode
      open(PTY, "+>/dev/pty$bank$unit") || next;
      $s = select(PTY); $| = 1; select($s);
      open(TTY, "+>/dev/tty$bank$unit") || next;
      $s = select(TTY); $| = 1; select($s);
      last found;
      }
    }
  die "$0: Cannot find a free pty\n";
  }

Let me know if anybody cares.

Attachments
#!/usr/bin/perl -w

use strict;

use Fcntl; # Needed for O_RDWR and O_NOCTTY flags to sysopen

use POSIX qw/setsid ttyname/;
use POSIX ":sys_wait_h";

my $s;
my $pid;
my $ptyname;
my $passwd = "/usr/bin/passwd";
my $buf;
my $kid;

if( $#ARGV < 1 ) {
    print "Usage: $0 {Old} {New}\n";
    exit 0;
}

my $Old = shift;
my $New = shift;

# Open the control side and set non blocking
sysopen( PTC, "/dev/ptc", O_RDWR | O_NOCTTY ) or die "Can't open a pseudo-terminal. $!";
$s = select(PTC); $| = 1; select($s);

# Get the name of the slave side
$ptyname = ttyname(fileno(PTC));

$pid = fork;
if ($pid < 0) {
 die "Can't fork: $1\n";
}

if ($pid == 0) { # I'm the son ; exec the program...
  # Break away from the cold controling terminal.
  setsid() or die "Can't setsid: $!\n";

  # Open the slave side of the new one and set non-blocking IO
  sysopen( PTS, $ptyname, O_RDWR ) or die "Can't open a pseudo-terminal (child). $!";
  $s = select(PTS); $| = 1; select($s);

  close STDIN;
  close STDOUT; 
  close STDERR;
  open(STDIN,"<&PTS");
  open(STDOUT,">&PTS");
  open(STDERR,">&STDOUT");
  $| = 1;
  exec $passwd;
}

$| = 1;
while( sysread(PTC, $_, 1) ) {
    print "$_";
    $buf = $buf . $_;
    if( $buf =~ /Enter the new password again:/ ) {
        $buf = "";
        syswrite( PTC, $New . "\n" );
    }
    if( $buf =~ /New password: / ) {
        $buf = "";
        syswrite( PTC, $New . "\n" );
    }
    if( $buf =~ /Old password: / ) {
        $buf = "";
        print "Sending $Old\n";
        syswrite( PTC, $Old . "\n" );
    }
    if( ($kid = waitpid(-1, WNOHANG)) > 0 ) {
        last;
    }
}

close( PTC );
exit 0;

I am interested if you ever get the Berkly style working, I would like to see it.

I am interested if you ever get the Berkly style working, I would like to see it.

Hi Amit,

Im looking for the script which you have for changing password on multiple servers. Would you mind sending them to me at.

Thanks and regards,
VinodKumar

Hi folks !!!!

First of all i am sorry for not replying to your posts.

Please let me know if you still require the script and i will post it in the thread.

Thanks,
Amit

Hi folks !!!!

First of all i am sorry for not replying to your posts.

Please let me know if you still require the script and i will post it in the thread.

Thanks,
Amit

If you could post the script I would very much appreciate it :)

Shelby

i am using a shell script which changes the password of all the servers in the network and also of the host server (as per your requirement) but it uses except.

Earlier i had a perl script to change the password.

If you want i can give you both the scripts and you can modify them as per your requirement.

Amit

Hello Amit,
I was looking out for such script. I have to change user password for several servers.Would you mind sending me both the scripts at neha.ao@gmail.com ? It would be a great help.

Hello AMIT,

I almost need the same script. What I have is a root password which needs to be same on all servers. So these would be the requirements
> Script will have the root password
> The script will change the existing password and will insert the one which I have give
> Later it will ask me to type it from the keyboard to verify it
Do u have such kind off script..It would be great if you can please share it
Sri

i am using a shell script which changes the password of all the servers in the network and also of the host server (as per your requirement) but it uses except.

Earlier i had a perl script to change the password.

If you want i can give you both the scripts and you can modify them as per your requirement.

Amit

Amit,
First, THANK YOU for posting the script.

I get the following error when attempting to run this on a SUN box.

Can't open a pseudo-terminal. No such file or directory at ttypasswd.pl line 26.

I'm hoping to change the root password across many servers via a script. This script appears to change the password for the initiating user.

On my target servers, I'll need to su - to the root account since we can't login directly as root.

I have a file that contains that the hostnames for all my target servers and I would like the script to parse this file.

Thank you in advance for any assistance you can provide.
Chris

hello Amit,

I also need change user password across multiple servers, could you send both of your scripts to bjgyking@163.com.
Your help will be highly apprieciated!!!

Would you please e-mail the original script that changes the password across many servers?
Thanks

i have attached the modified script beacuse the original script is for changing the password across multiple servers and i guess this is not what you require.

You need to execute the script from root user. It will create a log file in the directory from which you are executing the script.

You can change the password for root and a user but you can do a small modification and the script will change the password for root and any user.

Amit

hello amit,
can you plase send to me the version that changes on multiple servers? Is it perl script?
Thank you,
ebbtibde

i am using a shell script which changes the password of all the servers in the network and also of the host server (as per your requirement) but it uses except.

This article has been dead for over six months. Start a new discussion instead.