简体   繁体   English

在Python中按照给定的UID执行shell命令

[英]Executing shell commands as given UID in Python

I need a way to execute the os.system() module as different UID's. 我需要一种将os.system()模块作为不同的UID执行的方法。 It would need to behave similar to the following BASH code (note these are not the exact commands I am executing): 它的行为必须类似于以下BASH代码(请注意,这些不是我正在执行的确切命令):

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

The target platform is GNU Linux Generic. 目标平台是GNU Linux Generic。

Of course I could just pass these to the os.system module, but how to send the password? 当然,我可以将它们传递给os.system模块,但是如何发送密码? Of course I could run the script as root, but that's sloppy and insecure. 当然,我可以以root身份运行脚本,但这是草率且不安全的。

Preferably I would like to do with without requiring any passwords to be in plain text. 最好是我希望在不要求任何密码为纯文本的情况下进行处理。

I think that's not trivial: you can do that with a shell because each command is launched into its own process, which has its own id. 我认为这并非易事:您可以使用Shell来完成此操作,因为每个命令都会启动到自己的进程中,该进程具有自己的ID。 But with python, everything will have the uid of the python interpreted process (of course, assuming you don't launch subprocesses using the subprocess module and co). 但是,使用python时,所有内容都将具有python解释过的进程的uid(当然,假定您不使用subprocess模块​​和co启动子进程)。 I don't know a way of changing the user of a process - I don't know if that's even possible - even if it were, you would at least need admin privileges. 我不知道更改流程用户的方法-我也不知道是否可能-即使是这样,您至少也需要管理员权限。

What are you trying to do exactly ? 您到底想做什么? This does not sound like the right thing to do for admin purpose, for example. 例如,这听起来不适合管理目的。 Generally, admin scripts run in a priviledge user - because nobody knows the password of user 2 except user 2 (in theory). 通常,管理脚本以特权用户身份运行-因为除了用户2(理论上)之外,没人知道用户2的密码。 Being root means su user always work for a 'normal' user, without requesting password. 成为root用户意味着su用户始终为“普通”用户工作,而无需输入密码。

maybe sudo can help you here, otherwise you must be root to execute os.setuid 也许sudo可以在这里为您提供帮助,否则您必须是root用户才能执行os.setuid

alternatively if you want to have fun you can use pexpect to do things something like this, you can improve over this 或者,如果您想玩得开心,可以使用pexpect做类似的事情,您可以在此基础上进行改进

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

The function you're looking for is called os.seteuid . 您要查找的函数称为os.seteuid I'm afraid you probably won't escape executing the script as root, in any case, but I think you can use the capabilities(7) framework to 'fence in' the execution a little, so that it can change users--but not do any of the other things the superuser can. 恐怕无论如何,您可能都不会逃脱以root身份执行脚本,但是我认为您可以使用capabilities(7)框架来“限制”执行,以便它可以更改用户-但不能执行超级用户可以执行的其他任何操作。

Alternatively, you might be able to do this with PAM. 另外,您也许可以使用PAM执行此操作。 But generally speaking, there's no 'neat' way to do this, and David Cournapeau is absolutely right that it's traditional for admin scripts to run with privileges. 但总的来说,没有“整洁”的方法可以做到这一点,David Cournapeau绝对正确,因为传统上使用特权运行管理脚本。

Somewhere along the line, some process or other is going to need an effective UID of 0 (root), because only such a process can set the effective UID to an arbitrary other UID. 在此过程中,某个进程或其他进程将需要有效的UID为0(根),因为只有这样的进程才能将有效的UID设置为任意其他UID。

At the shell, the su command is a SUID root program; 在外壳程序上, su命令是一个SUID根程序; it is appropriately privileged (POSIX jargon) and can set the real and effective UID. 它具有适当的特权(POSIX术语),并且可以设置真实有效的UID。 Similarly, the sudo command can do the same job. 同样, sudo命令可以完成相同的工作。 With sudo , you can also configure which commands and UID are allowed. 使用sudo ,您还可以配置允许哪些命令和UID。 The crucial difference is that su requires the target user's password to let you in; 关键区别在于su需要目标用户的密码才能进入。 sudo requires the password of the user running it. sudo需要运行它的用户的密码。

There is, of course, the issue of whether a user should know the passwords of other users. 当然,存在一个问题,即用户是否应该知道其他用户的密码。 In general, no user should know any other user's password. 通常,没有用户应该知道任何其他用户的密码。

Scripting UID changes is hard. 用脚本编写UID更改很难。 You can do: 你可以做:

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

However, su will demand a password from the controlling terminal (and will fail if there is no controlling terminal). 但是, su将要求控制终端提供密码(如果没有控制终端,则将失败)。 If you use sudo , it will cache credentials (or can be configured to do so) so you only get asked once for a password - but it will prompt the first time just like su does. 如果使用sudo ,它将缓存凭据(或可以将其配置为缓存凭据),因此只要求您输入一次密码-但它将像su一样第一次提示您。

Working around the prompting is hard. 解决提示很困难。 You can use tools parallel to expect which handle pseudo-ttys for you. 您可以使用并行工具来expect为您处理伪tty。 However, you are then faced with storing passwords in scripts (not a good idea) or somehow stashing them out of sight. 但是,您将面临将密码存储在脚本中(不是一个好主意)或以某种方式将其藏在看不见的地方。


The tool I use for the job is one I wrote, called asroot . 我用于这项工作的工具是我写的一个名为asroot It allows me to control precisely the UID and GID attributes that the child process should have. 它使我可以精确控制子进程应具有的UID和GID属性。 But it is designed to only allow me to use it - that is, at compile time, the authorized username is specified (of course, that can be changed). 但是它的设计仅允许我使用它-也就是说,在编译时,将指定授权的用户名(当然,可以更改)。 However, I can do things like: 但是,我可以执行以下操作:

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

This sets the real and effective UID to 'someone', sets the primary group to 'theirgrp', removes all auxilliary groups, and adds 'othergrp' (so the process belongs to just two groups) and sets the umask to 0222; 这会将真实有效的UID设置为“某人”,将主要组设置为“ theirgrp”,删除所有辅助组,并添加“ othergrp”(因此该过程仅属于两个组)并将umask设置为0222; it then executes 'somecmd' with the arguments given. 然后使用给定的参数执行“ somecmd”。

For a specific user who needs limited (or not so limited) access to other user accounts, this works well. 对于需要有限(或不那么有限)访问其他用户帐户的特定用户,这很好。 As a general solution, it is not so hot; 作为一般解决方案,它并不那么热。 sudo is better in most respects, but still requires a password (which asroot does not). sudo在大多数方面sudo较好,但是仍然需要密码( asroot不需要)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM