Выполнение команд оболочки в соответствии с заданным UID в Python

StackOverflow https://stackoverflow.com/questions/981052

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

p = pexpect.spawn("su guest")
p.logfile = sys.stdout 
p.expect('Password:')
p.sendline("guest")

Где-то в процессе тому или иному процессу понадобится эффективный UID, равный 0 (корневой), потому что только такой процесс может установить эффективный 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 не).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top