2016-07-21 2 views
0

У меня есть скрипт python (который должен быть вызван как root), который вызывает сценарий bash (который должен вызываться как не root), который иногда требует вызова sudo. Это не работает - «листовые» sudo-вызовы дают сообщение «$ user не находится в файле sudoers. Этот инцидент будет сообщен». Как я могу сделать эту работу?sudo/suid non-root nesting failed

Код (вставить Некорневые имя пользователя вместо "your_username_here"):

tezt.py:

#!/usr/bin/python3 

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(): 
    os.setgid(user_obj.pw_gid) 
    os.setuid(user_obj.pw_uid) 

    return subprocess.Popen(
    cmd_args, 
    preexec_fn=suid_func, 
    cwd=cwd, 
    env=new_env, 
    **kwargs).wait() == 0 

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

tezt:

#!/bin/bash 

sudo ls -la /root 

Затем запустите его как:

sudo ./tezt.py 

Кто-нибудь знает, почему это не работает? Пользователь может запускать sudo при нормальных обстоятельствах. Почему «user -sudo-> root -suid-> user» работает нормально, но тогда, когда вы пытаетесь sudo оттуда, он терпит неудачу?

+0

Почему УИП()/setgid() вызывает себя, вместо того чтобы использовать Sudo уронить привилегии там? '[" sudo "," -u "," your_username_here "," - ", cmd_args]' –

+0

Рассмотрите также переход на 'setreuid()' и 'setregid()'. –

+0

С 'setreuid/setregid' Я получаю бесполезное исключение из функции preexec_fn. Но с добавлением sudo к аргументу команды это работает! Все еще не уверен, что здесь происходит, но спасибо за решение, @CharlesDuffy! –

ответ

1

Я предлагаю использовать sudo, чтобы отбрасывать привилегии, а не делать это самостоятельно - это, по возможности, немного более основательно, изменяя эффективные, а не только реальные uid и gid. (Чтобы полностью изменить настройки, вы можете попробовать изменить setuid() на setreuid(), а также setgid() на setregid()).

... это означало бы, передавая что-то похожее на POPEN следующее:

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