Выполнение команд оболочки с заданным UID в Python - PullRequest
0 голосов
/ 11 июня 2009

Мне нужен способ выполнить модуль os.system () как разные UID. Он должен вести себя подобно следующему коду BASH (обратите внимание, что это не точные команды, которые я выполняю):

su user1
ls ~
mv file1
su user2
ls ~
mv file1

Целевой платформой является GNU Linux Generic.

Конечно, я мог бы просто передать их в модуль os.system, но как отправить пароль? Конечно, я мог запустить скрипт от имени пользователя root, но это небрежно и небезопасно.

Желательно, чтобы я хотел обойтись без паролей в виде простого текста.

Ответы [ 4 ]

3 голосов
/ 11 июня 2009

Я думаю, что это не тривиально: вы можете сделать это с помощью оболочки, потому что каждая команда запускается в своем собственном процессе, который имеет свой собственный идентификатор. Но с python все будет иметь uid интерпретируемого процесса на python (конечно, если вы не запускаете подпроцессы с использованием модуля subprocess и co). Я не знаю, как изменить пользователя процесса - я не знаю, возможно ли это вообще - даже если бы это было так, вам, по крайней мере, потребовались бы права администратора.

Что вы пытаетесь сделать именно? Это не похоже на то, что нужно делать, например, для администратора. Как правило, административные сценарии выполняются от имени привилегированного пользователя - потому что никто не знает пароль пользователя 2, кроме пользователя 2 (теоретически). Быть root означает, что su user всегда работает для «обычного» пользователя без запроса пароля.

2 голосов
/ 11 июня 2009

возможно, sudo может вам помочь, в противном случае вы должны быть пользователем root, чтобы выполнить os.setuid

в качестве альтернативы, если вы хотите повеселиться, вы можете использовать pexpect, чтобы делать вещи что-то вроде этого, вы можете улучшить это

p = pexpect.spawn("su guest")
p.logfile = sys.stdout 
p.expect('Password:')
p.sendline("guest")
1 голос
/ 11 июня 2009

Где-то на пути к тому или иному процессу или другому потребуется эффективный UID 0 (root), потому что только такой процесс может установить эффективный UID на произвольный другой UID.

В оболочке команда su является корневой программой SUID; он имеет соответствующие привилегии (жаргон POSIX) и может устанавливать реальный и эффективный UID. Аналогично, команда sudo может выполнять ту же работу. С sudo вы также можете указать, какие команды и UID разрешены. Принципиальное отличие состоит в том, что su требует пароль целевого пользователя, чтобы впустить вас; sudo требуется пароль пользователя, который его запускает.

Конечно, существует вопрос о том, должен ли пользователь знать пароли других пользователей. Как правило, ни один пользователь не должен знать пароль другого пользователя.

Сценарии изменения UID сложно. Вы можете сделать:

su altuser -c "commands to execute as altuser"
sudo -u altuser commands to execute as altuser

Однако, su потребует пароль от управляющего терминала (и потерпит неудачу, если нет управляющего терминала). Если вы используете sudo, он будет кэшировать учетные данные (или может быть настроен для этого), поэтому вам будет предложено ввести пароль только один раз, но в первый раз будет предложено, как su.

Работать с подсказками сложно. Вы можете использовать инструменты, параллельные expect, которые обрабатывают псевдо-тты для вас. Однако вы сталкиваетесь с необходимостью хранить пароли в скриптах (не очень хорошая идея) или каким-то образом скрывать их от глаз.


Инструмент, который я использую для работы, - тот, который я написал, называется asroot. Это позволяет мне точно контролировать атрибуты UID и GID, которые должен иметь дочерний процесс. Но он предназначен только для того, чтобы я мог его использовать, то есть во время компиляции указывается авторизованное имя пользователя (конечно, это можно изменить). Тем не менее, я могу делать такие вещи, как:

asroot -u someone -g theirgrp -C -A othergrp -m 022 -- somecmd arg1 ...

Это устанавливает действительный и эффективный UID на «кого-то», устанавливает первичную группу на «их группы», удаляет все вспомогательные группы и добавляет «другие группы» (поэтому процесс принадлежит только двум группам) и устанавливает значение umask 0222. ; затем он выполняет 'somecmd' с заданными аргументами.

Для конкретного пользователя, которому нужен ограниченный (или не столь ограниченный) доступ к другим учетным записям, это работает хорошо. Как общее решение, это не так жарко; sudo лучше во многих отношениях, но все равно требует пароль (а asroot - нет).

1 голос
/ 11 июня 2009

Функция, которую вы ищете, называется os.seteuid. Боюсь, что в любом случае вы, вероятно, не избежите выполнения скрипта от имени пользователя root, но я думаю, что вы можете использовать фреймворк capabilities(7), чтобы немного «ограничить» выполнение, чтобы он мог менять пользователей - но не делать ничего другого, что может суперпользователь.

В качестве альтернативы, вы могли бы быть в состоянии сделать это с PAM. Но, вообще говоря, нет «аккуратного» способа сделать это, и Дэвид Курнапо абсолютно прав, что для административных сценариев традиционно работают привилегии.

...