Стандартным способом [только для POSIX] будет использование preexec_fn
для установки gid и uid, как более подробно описано в этот ответ
Что-то подобное должно сработать - - для полноты я также изменил ваш исходный фрагмент кода, включив в него другие переменные окружения, которые вы, вероятно, захотите установить, но достаточно просто установить preexec_fn
для простой команды, которую вы выполняете:
import os, pwd, subprocess
def demote(user_uid, user_gid):
def result():
os.setgid(user_gid)
os.setuid(user_uid)
return result
def exec_cmd(username):
# get user info from username
pw_record = pwd.getpwnam(username)
homedir = pw_record.pw_dir
user_uid = pw_record.pw_uid
user_gid = pw_record.pw_gid
env = os.environ.copy()
env.update({'HOME': homedir, 'LOGNAME': username, 'PWD': os.getcwd(), 'FOO': 'bar', 'USER': username})
# execute the command
proc = subprocess.Popen(['echo $USER; touch myFile.txt'],
shell=True,
env=env,
preexec_fn=demote(user_uid, user_gid),
stdout=subprocess.PIPE)
proc.wait()
exec_cmd('www-data')
Обратите внимание, что вам также необходимо убедиться, что текущий рабочий каталог доступен (например, для записи) пониженному пользователю, поскольку он не переопределяет его явно