5

I am trying to use fabric to automate some administrative work that I am doing on a couple of servers. The general flow is the following:

  1. SSH with local user
  2. run: sudo su - to become root (providing local user password again)
  3. Do the work as root :)

Unfortunately using run('sudo su -') blocks execution of the scripts and allows user input. When I type exit or Ctrl+D the scipt resumes, but without root privileges.

I have seen a similar problem in Switching user in Fabric but I am restricted to sudo su - because I am not allowed to change the /etc/sudoers file which contains the following line:

localuser ALL = /usr/bin/su -

I browsed the source of fabric trying to find a workaround but with no success.

Community
  • 1
  • 1
Marin
  • 1,268
  • 12
  • 7
  • Take a look at http://docs.fabfile.org/en/1.4.2/usage/env.html#sudo-prefix and this example: http://stackoverflow.com/questions/12641514/switch-to-different-user-using-fabric – alecxe Feb 27 '13 at 14:37
  • Using `sudo_prefix='su - -c '` as described in that post requires the root password. If I use `sudo_prefix='sudo su - -c '` I get this error message `Sorry, user localuser is not allowed to execute '/usr/bin/su - -c /bin/bash -l -c pwd' as root on hostname.` – Marin Feb 27 '13 at 16:34
  • Setting `shell=False` seems to have no effect. Setting `pty=False` returns the error `sudo: no tty present and no askpass program specified` – Marin Feb 28 '13 at 07:15

3 Answers3

4

Having faced the same problem as yours, (only sudo su - user allowed by admin, sudo -u user -c cmd not allowed), here's my working solution with fabric:

from ilogue.fexpect import expect, expecting, run 

def sudosu(user, cmd):
    cmd += ' ;exit'
    prompts = []
    prompts += expect('bash', cmd)
    prompts += expect('assword:', env.password)

    with expecting(prompts):
        run('sudo su - ' + user)

def host_type():
    sudosu('root', 'uname -s')
Amaury D
  • 475
  • 4
  • 7
2

There are several solutions for your issue. First, you want to run commands using sudo. You can use the fabric method sudo instead of run that runs a shell command on a remote host, with superuser privileges(sudo ref).

For example, these commands are executed using sudo :

sudo("~/install_script.py")
sudo("mkdir /var/www/new_docroot", user="www-data")
sudo("ls /home/jdoe", user=1001)
result = sudo("ls /tmp/")

Another idea is that you want to wrap a set of commands (that need to be sudoed). You can use Fabric context managers (ref) to do that. Particularly, you can use prefix or settings.

For example:

with settings(user='root'):
    run('do something')
    run('do another thing')

will ask you once the root password then execute commands as root. You can tweek settings to store the password.

driquet
  • 679
  • 5
  • 4
  • Both the solutions do not work for me. I have tried the first one and the `sudo('pwd')` translates to `sudo -S -p 'sudo password:' /bin/bash -l -c "pwd"` and I get an error message `Sorry, user localuser is not allowed to execute '/bin/bash -l -c pwd' as root on hostname.` The second solutions implies that I have the root password which I don't. – Marin Feb 27 '13 at 15:39
  • For the second solution, cant you use the password you would use normally to get superuser access? – gbozee Aug 09 '16 at 19:20
0

There is one solution for the following problem Sorry, user localuser is not allowed to execute '/usr/bin/su - -c /bin/bash -l -c pwd' as root on hostname. You can try sudo('mkdir ~/test_fabric',shell=False). Using param shell to avoid the bash param -l.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140