ACK_stoverflow ACK_stoverflow - 3 months ago 6x
Linux Question

sudo/suid non-root nesting fails

I have a python script (which must be called as root), which calls a bash script (which must be called as non-root), which sometimes needs to call sudo. This does not work - the "leaf" sudo calls give the message "$user is not in the sudoers file. This incident will be reported." How can I make this work?

The code (insert your non-root username in place of "your_username_here"):


import os
import pwd
import subprocess

def run_subshell_as_user(cmd_args, user_name=None, **kwargs):
cwd = os.getcwd()
user_obj = pwd.getpwnam(user_name)

# Set up the child process environment
new_env = os.environ.copy()
new_env["PWD"] = cwd
if user_name is not None:
new_env["HOME"] = user_obj.pw_dir
new_env["LOGNAME"] = user_name
new_env["USER"] = user_name

# This function is run after the fork and before the exec in the child
def suid_func():

return subprocess.Popen(
**kwargs).wait() == 0

run_subshell_as_user(["./tezt"], "your_username_here") # <-- HERE



sudo ls -la /root

Then run it as:

sudo ./

Does anyone know why this doesn't work? The user can run sudo under normal circumstances. Why does "user -sudo-> root -suid-> user" work fine, but then when you try to sudo from there it fails?


I'd suggest using sudo to drop privileges rather than doing so yourself -- that's a bit more thorough where possible, modifying effective as opposed to only real uid and gid. (To modify the full set yourself, you might try changing setuid() to setreuid(), and likewise setgid() to setregid()).

...this would mean passing something to Popen akin to the following:

["sudo", "-u", "your_username_here", "--"] + cmd_args