I have this simple python script that run as root, but will execute subprocesses as some other user:
#!/usr/bin/env python2
import subprocess
import os
def demote(user_uid):
def result():
os.setuid(user_uid)
return result
cmd = "echo $USER"
proc = subprocess.Popen(cmd, preexec_fn=demote(1000), stdout=subprocess.PIPE, shell=True)
output = proc.communicate()[0]
print output
If cmd is "sleep 60" then the script spawns sleep as the user:
# ps -ef | grep sleep
dave 17812 17811 0 17:05 pts/5 00:00:00 /usr/bin/sleep 60
However, if cmd is 'echo $USER', the outout is "root". Is there someone I need to do to get the user's env if I spawn the subprocess as a nother user?
You don't really have a problem with subprocess here. Subprocess is getting passed the environment from your current environment, so when you "echo $USER", it's reporting the user from the current environment.
See what happens when you change the command to whoami
, which actually checks your UID:
My python shell is running as root:
>>> print os.getuid()
0
But changing the command being run outputs the correct new user:
>>> cmd = "whoami"
>>> proc = subprocess.Popen(cmd, preexec_fn=demote(1000), stdout=subprocess.PIPE, shell=True)
>>> output = proc.communicate()[0]
>>> print output
voodoonofx
If you really want to modify the environment to be that user, you could pass a new dictionary to the Popen call. See the env keyword passed with help(subprocess.Popen):
__init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
Create new Popen instance.