slayedbylucifer has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I want to change password of root on remote machine using "NET::SSH::Expect". Per the module writer's release notes on CPAN, we have to use "send...waitfor...send" combination to work with interactive commands. In my case, the "send" part just never seem to work. The way my script is going, it looks like it completely overlooks "send" statement.

Here is my code:

#!/usr/bin/perl use strict; use warnings; use Net::SSH::Expect; my $ssh = Net::SSH::Expect-> new ( host => "10.10.10.10", password => "abcdefg", user => "root", raw_pty => 1, timeout => 3 ); my $login_output=$ssh->login(); if ( $login_output =~ /Last/ ) { print "The login was successful \n"; print "Let's change the password of root on remote server now \n"; $ssh->send("passwd"); $ssh->waitfor('password:\s',10) or die "Where is the password promp +t??"; $ssh->send("new_pass"); $ssh->waitfor('password:\s*\z',10) or die "Where is the password pr +ompt??"; $ssh->send("new_passwd"); } else { die "Log in attempt failed with $! \n"; }

to check whether my script is *actually* reading "send" statement, I ran following and it ignored it completely.

$ssh->send("find /");

but below "exec" statement works just fine.

$ssh->exec("find /");

Hence I tried using "exec" for change password in above script, but it always dies with the error that i have mentioned in the script "Where is the password prompt??" please help.

Thanks.

Replies are listed 'Best First'.
Re: Run interactive commands with "Net::SSH::Expect"
by zentara (Cardinal) on Jan 10, 2011 at 12:06 UTC
    I want to change password of root on remote machine

    Most systems setup now, disallow root logins on telnet and ssh. It is usually setup that you login as a regular, special user, who can then run the sudo command to change the password.

    This gives more security, through the sudo mechanism.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      Thanks Zentara for taking time to go through my thread. I understand the security aspect. For this particular case, I have enabled root ssh on my system. I want to leave aside the security and make this script work. My ultimate aim is to change the password for root (or any other user for that sake) on a remote server using this script.

      This is my test environment running inside my virtualbox on my laptop, so things are cool...

      If I make this script this work, I will have a bigger implementation in my PROD environment, where of course, I can't log in as root via ssh

Re: Run interactive commands with "Net::SSH::Expect"
by molecules (Monk) on Jan 10, 2011 at 15:28 UTC
    Have you tried changing the pattern for matching the password prompt? Perhaps the following to allow any (or no) number of spaces:
    'password:\s*'
    Have you tried increasing your timeout?
    $ssh->waitfor('password:\s*',100) or die "Where is the password prompt +??";
    You might also want to make each error message within your program unique, so that you know for sure where the error is occurring.
    $ssh->waitfor('password:\s*',100) or die "Where is the FIRST password +prompt??";

      I had tried that option, But I tried it one more time after reading your response....

      I increased the time out period aslo I used "\s*" to match number of spaces. But no luck. Here is hte output:

      # ./change_password.pl The login was successful Let's change the password of root on remote server now

      I am pretty sure that my script is ignoring the "send" statements and then apparently dying.

      Thanks for taking time to provide your feedback.

        OK, I have made some progress. I ran the perl debugger and after the 2nd print statement, the debugger throws following error:

        croak (ILLEGAL_ARGUMENT . " missing argument 'string'.") unless ($send +); croak (ILLEGAL_STATE_NO_SSH_CONNECTION);

        When I look into the "package Net::SSH::Expect", it is mentioned right on the top that:

        use constant ILLEGAL_STATE_NO_SSH_CONNECTION => "IllegalState: you don +'t have a valid SSH connection to the server";

        So,..my assumption in my previous replies was correct, the script is ignoring the "send " statement because now I realize that by teh time the script reaches to execute the "send" statement, the ssh connection does not remain active.

        Could you please help me figure this out, I cannot reason why would my ssh connection get closed ??

Re: Run interactive commands with "Net::SSH::Expect"
by salva (Canon) on Jan 13, 2011 at 12:25 UTC

      Finally, after playing around with perl debugger, I got my script working. here is the code:

      #!/usr/bin/perl use strict; use warnings; use Net::SSH::Expect; my $ssh = Net::SSH::Expect-> new ( host => "10.10.10.10", password => "current_password", user => "root", raw_pty => 1, timeout => 10, log_file => "log_file" # this line actually got my head spinn +ing in right direction ); my $login_output=$ssh->login(); if ( $login_output =~ /Last/ ) { print "The login for ROOT was successful, Let's see if we can chang +e the password \n"; $ssh->send("passwd"); $ssh->waitfor ('password:\s*', 10) or die "Where is the first passw +ord prompt??"; $ssh->send("new_password"); $ssh->waitfor ('password:\s*', 10) or die "Where is the Second pass +word promp??"; $ssh->send("new-password"); $ssh->waitfor('passwd:\s*',5); # And this was the kicker, I was mis +sing this in my original script print "The password for ROOT has been changed successfully \n"; } else { die "The log in for ROOT was _not_ successful.\n"; }

      Thnx for all the responses.

      @Salva: Thanks for your script. It was a much needed one. I haven't yet tried your script but I will soon try it out.