Linux – run script as another user from a root script with no tty stdin

centosdaemontoolslinuxshellsu

Using CentOs, I want to run a script as user 'training' as a system service. I use daemontools to monitor the process, which needs a launcher script that is run as root and has no tty standard in.

Below I give my five different attempts which all fail.

  1. :

    #!/bin/bash
    exec >> /var/log/training_service.log 2>&1
    setuidgid training training_command
    

    This last line is not good enough since for training_command, we need environment for trqaining user to be set.

  2. :

    su - training -c 'training_command' 
    

    This looks like it (Run a shell script as a different user) but gives 'standard in must be tty' as su making sure tty is present to potentially accept password. I know I could make this disappear by modifying /etc/sudoers (a la https://superuser.com/questions/119376/bash-su-script-giving-an-error-standard-in-must-be-a-tty) but i am reluctant and unsure of consequences.

  3. :

    sudo -u training -i bash -c 'source $HOME/.bashrc; training_command'
    

    A variation on the same theme: 'sudo: sorry, you must have a tty to run sudo'

  4. :

    runuser - training -c 'training_command'  
    

    This one gives runuser: cannot set groups: Connection refused. I found no sense or resolution to this error.

  5. :

    ssh -p100 training@localhost 'source $HOME/.bashrc; training_command'
    

    This one is more of a joke to show desparation. Even this one fails with Host key verification failed. (the host key IS in known_hosts, etc).

Note: all of 2,3,4 work as they should if I run the wrapper script from a root shell. problems only occur if the system service monitor (daemontools) launches it (no tty terminal I guess).

I am stuck. Is this something so hard to achieve?

I appreciate all insight and guidance to best practice.

(this has also been posted on superuser: https://superuser.com/questions/434235/script-calling-script-as-other-user)

Best Answer

You will need to disable the requiretty setting in /etc/sudoers for root. Add the following line via visudo:

Defaults:root !requiretty

You will also need the following line in /etc/sudoers so root can do everything (this should be enabled by default, but check to be sure):

root ALL=(ALL) ALL

Then you can do the following:

sudo -u training /path/to/training_command