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

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

I am trying to use the Net::SSH::Perl module ( that one being the pure perl module, as opposed to Net::SSH which is a wrapper around system() calls ) and running an 'su' on a remote box. It isn't working.

Specifically, I cannot seem to get the Net::SSH::Perl->cmd method to respond to the password: prompt. It appears the remote 'su' is timing out while waiting for input.

Has anybody else done this? If so, how? I have looked at installing my own handler, but thought to see how somebody else has done this before I hurt myself figuring it out.

Any help I could get from my fellow monks would be most appreciated.

For what it is worth, my code looks like:

#!/usr/local/bin/perl -w use strict; use Net::SSH::Perl; use Data::Dumper; # I set the use_pty because that was the only way I could # get this to work using /usr/local/bin/ssh. It is really # only a guess. my $ssh = Net::SSH::Perl->new( "172.20.28.48", debug => 1, protocol => + 2, use_pty => 1 ); $ssh->login(); my ($out, $err, $exit ) = $ssh->cmd('su - root -c "touch /var/tmp/sill +y3"', '*******'); print "out = $out\nerr = $err\nexit = $exit\n";
and the (slightly truncated) debug output looks like this:
borris: Login completed, opening dummy shell channel. borris: channel 0: new [client-session] borris: Requesting channel_open for channel 0. borris: channel 0: open confirm rwindow 0 rmax 32768 borris: Got channel open confirmation, requesting shell. borris: Requesting service shell on channel 0. borris: channel 1: new [client-session] borris: Requesting channel_open for channel 1. borris: Entering interactive session. borris: Sending command: su - root -c "touch /var/tmp/silly3" borris: Requesting service exec on channel 1. borris: channel 1: send eof borris: channel 1: open confirm rwindow 131065 rmax 32768 borris: input_channel_request: rtype exit-status reply 0 borris: channel 1: rcvd eof borris: channel 1: output open -> drain borris: channel 1: rcvd close borris: channel 1: obuf empty borris: channel 1: output drain -> closed borris: channel 1: close_write borris: channel 1: send close borris: channel 1: full closed Use of uninitialized value in concatenation (.) or string at su.pl lin +e 12. out = err = su: Sorry exit = 1

mik
mikfire

Replies are listed 'Best First'.
Re: Net::SSH::Perl and su
by fuzzyping (Chaplain) on Mar 08, 2002 at 21:26 UTC
    I was having the same problem myself with a project I'm working on. The following excerpt from the Net::SSH::Perl documentation may be pertinent...

    "..if you're running in an interactive session and you've not provided a password, you'll be prompted for one..."

    But what is interactive mode? It appears to be through the use of Net::SSH::Perl->shell(), which "Opens up an interactive shell on the remote machine and connects it to your STDIN. This is most effective when used with a pseudo tty; otherwise you won't get a command line prompt, and it won't look much like a shell. For this reason--unless you've specifically declined one--a pty will be requested from the remote machine, even if you haven't set the use_pty argument to new..."

    It sounds like the only way to connect interactively is to use shell() or grab the password, handing it off to login() beforehand. Hope this helps.

    -fuzzyping

    UPDATE:

    The problem is not what I described above... you're simply missing the interactive option with login. Your code should look something like...
    #!/usr/local/bin/perl -w use strict; use Net::SSH::Perl; use Data::Dumper; my $ssh = Net::SSH::Perl->new( "localhost", debug => 1, protocol => 2, + interactive => 1, use_pty => 1 ); $ssh->login(); my ($out, $err, $exit ) = $ssh->cmd('su - root -c "touch /var/tmp/sill +y3"', '*******'); print "out = $out\nerr = $err\nexit = $exit\n";

    FWIW, I'm still getting STDIN/tty errors to $err, but it is running interactively and asking for my password. It appears to be a limitation of su, requiring local tty control(?). There are others here who would be better qualified to answer that one. I have no problem running non-su commands, though. Good Luck!

    -fuzzyping
      FWIW, I'm still getting STDIN/tty errors to $err, but it is running interactively and asking for my password. It appears to be a limitation of su, requiring local tty control(?). There are others here who would be better qualified to answer that one. I have no problem running non-su commands, though. Good Luck!

       

      I think the best solution for mikfire with this problem would be to investigate the use of sudo - This command allows administrators to grant permissions to users to execute priviledged commands without having to su to root. The advantage with this command offers in this scenario however is that, when configured as such, it allows priviledged commands to be executed by users without prompting for a password.

       

      perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

        something I really don't get is:
        "Why ssh to a remote machine (as a regular user), THEN su to root?"
        Assuming the user is "hossman" on both machines, you're doing this...
            hossman@client =ssh=> hossman@server =su=> root@server
        

        Why not do this instead...

            hossman@client =ssh=> root@server
        

        (sudo is nice because it eliminates the need for hossman to know the root password on server, but the same thing could be accomplished using ssh keys.)

        Alas, if only it were that easy. I can't use sudo for two main reason. First, the command I want to run is going to change. Second, due to some serious security concerns, there is no way I could convince them to allow me to use the NOPASSWD option in sudo.

        mikfire

      I have tried this. I doesn't work for me. I am beginning to think this problem is with respect to my version of Solaris and SSH ( Solaris 8 and SSH 3.1p1 ( you have patched your ssh, haven't you?) ).

      I have tried the example code ( which, having finally read, gave some fairly good examples on setting up callbacks ) and that doesn't work for me either. :/

      Thanks for the help, though.
      mikfire

        You might want to investigate the usage of keys with ssh. Although many say that this is less secure than asking for a password everytime, if you are thinking about storing passwords in plain text, this would be a great alternative.