python подпроцесс popen выполняется от имени другого пользователя - PullRequest
1 голос
/ 19 апреля 2020

Я пытаюсь выполнить команду в python 3.6 как другой пользователь с popen из subprocess, но она все равно будет выполняться как пользователь, вызвавший скрипт (я планирую вызвать его как root). Я использую потоки, и поэтому важно, чтобы я не нарушал права пользователя, когда 2 потока выполняются параллельно.

proc = subprocess.Popen(['echo $USER; touch myFile.txt'],
                          shell=True,
                          env={'FOO':'bar', 'USER':'www-data'},
                          stdout=subprocess.PIPE)

В приведенном выше примере все равно будет создано myFile.txt с моим user_id 1000

Я пробовал разные подходы:

  1. пытался, как описано в Запускать дочерние процессы от имени другого пользователя из долго выполняющегося Python процесса , копируя os.environment и изменил пользователя, и т. д. c
    (обратите внимание, что это для python 2)

  2. пробовал, как описано в https://docs.python.org/3.6/library/subprocess.html#popen -конструкторе с помощью start_new_session=True

Мой последний вариант - префикс команды с sudo -u username command, но я не думаю, что это элегантный способ.

1 Ответ

1 голос
/ 19 апреля 2020

Стандартным способом [только для 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')

Обратите внимание, что вам также необходимо убедиться, что текущий рабочий каталог доступен (например, для записи) пониженному пользователю, поскольку он не переопределяет его явно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...