Executing su user (without password) on paramiko ssh connection

apelliciari picture apelliciari · Dec 7, 2011 · Viewed 7k times · Source

I need to login in ssh to a server, do "su username" (without password) to execute some commands as that user (that have no direct login in ssh).

From the terminal it would be something like this:

root@cs01:~# su foo
foo@cs01:/root$ cd
foo@cs01:~$ ls

I've tried to do this with paramiko (python):

import paramiko
ssh = paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect('host', username='root', password='mypassword', key_filename='<filename>')

stdin, stdout, stderr = ssh.exec_command('su foo')
print stdout.readlines()
stdin, stdout, stderr = ssh.exec_command('cd')
print stdout.readlines()
stdin, stdout, stderr = ssh.exec_command('pwd')
print stdout.readlines()
ssh.close()

But the script doesn't end.

Logs are these:

...
DEB [20111207-16:22:25.538] thr=1   paramiko.transport: userauth is OK
INF [20111207-16:22:25.921] thr=1   paramiko.transport: Authentication (publickey) successful!
DEB [20111207-16:22:25.923] thr=2   paramiko.transport: [chan 1] Max packet in: 34816 bytes
DEB [20111207-16:22:26.088] thr=1   paramiko.transport: [chan 1] Max packet out: 32768 bytes
INF [20111207-16:22:26.088] thr=1   paramiko.transport: Secsh channel 1 opened.
DEB [20111207-16:22:26.151] thr=1   paramiko.transport: [chan 1] Sesch channel 1 request ok

If i try only this:

stdin, stdout, stderr = ssh.exec_command('su foo')
#without print
stdin, stdout, stderr = ssh.exec_command('pwd')
print stdout.readlines()

it executes the pwd as root, not as foo.

What's wrong?

Answer

JimB picture JimB · Dec 7, 2011

Each exec_command() call happens in a new shell, so there is no state carried over from previous commands. If commands rely on a previous command to execute, you have to send them in a single statement, or as a script. If you want an interactive shell, there is the invoke_shell command, but then you need to parse the shell output to simulate interactive use (the pexpect library can be used here).

You can use the sudo command, or su -c to execute the command.. However, I would suggest configuring a secure login for the needed user, and connecting as that user directly.