gpt4 book ai didi

python - 如何使用python在linux中以不同用户身份运行部分代码

转载 作者:太空宇宙 更新时间:2023-11-03 13:59:00 25 4
gpt4 key购买 nike

我正在寻找一种方法来运行部分 python 代码/函数以在 Linux 中作为不同的用户运行,而不是制作另一个脚本。

例如:

def function1(args):
# stuffs

def function2():
# stuffs

我想从 function2 调用函数 function1 并传递几个参数,function1 应该接受这些参数并执行这些东西作为不同的用户并返回结果。因为我必须在整个执行过程中调用一些东西,所以我不想为一小段代码创建多个脚本。基本上我试图在函数 function1 中连接数据库(数据库连接只能作为特定用户完成)并运行查询并获得结果。

最佳答案

这比您想象的要难一些。首先Python提供os.setuid()os.setguid()更改运行脚本的当前用户/组,您可以创建一个上下文管理器来为您出价并自动恢复为当前正在执行的用户:

import os

class UnixUser(object):

def __init__(self, uid, gid=None):
self.uid = uid
self.gid = gid

def __enter__(self):
self.cache = os.getuid(), os.getgid() # cache the current UID and GID
if self.gid is not None: # GID change requested as well
os.setgid(self.gid)
os.setuid(self.uid) # set the UID for the code within the `with` block

def __exit__(self, exc_type, exc_val, exc_tb):
# optionally, deal with the exception
os.setuid(self.cache[0]) # revert back to the original UID
os.setgid(self.cache[1]) # revert back to the original GID

并对其进行测试:

def test():
print("Current UID: {}".format(os.getuid())) # prints the UID of the executing user

test() # executes as the current user

with UnixUser(105):
test() # executes as the user with UID: 105

您甚至可以创建一个整洁的装饰器来选择某些功能应始终以其他用户身份执行:

def as_unix_user(uid, gid=None):  # optional group
def wrapper(func):
def wrapped(*args, **kwargs):
with UnixUser(uid, gid):
return func(*args, **kwargs) # execute the function
return wrapped
return wrapper

def test1():
print("Current UID: {}".format(os.getuid())) # prints the UID of the executing user

@as_unix_user(105)
def test2():
print("Current UID: {}".format(os.getuid())) # prints the UID of the executing user

test1() # executes as the current user
test2() # executes as the user with UID: 105

踢球者?除了不是线程安全的,它只有在当前用户和你想要执行函数的用户都具有 CAP_SETUID 时才有效。并且,可选地,CAP_SETGID能力。

您可以只让一个具有这些功能的用户运行主脚本,然后在必要时进行 fork ,仅在 fork 进程上更改 UID/GID:

import os

def as_unix_user(uid, gid=None): # optional group
def wrapper(func):
def wrapped(*args, **kwargs):
pid = os.fork()
if pid == 0: # we're in the forked process
if gid is not None: # GID change requested as well
os.setgid(gid)
os.setuid(uid) # set the UID for the code within the `with` block
func(*args, **kwargs) # execute the function
os._exit(0) # exit the child process
return wrapped
return wrapper

def test1():
print("Current UID: {}".format(os.getuid())) # prints the UID of the executing user

@as_unix_user(105)
def test2():
print("Current UID: {}".format(os.getuid())) # prints the UID of the executing user

test1() # executes as the current user
test2() # executes as the user with UID: 105

这里的踢球者?您不会从 fork 函数中获取返回数据。如果你需要它,你必须将它传回父进程,然后在父进程中等待它完成。您还需要选择一种格式来在进程之间传递数据(如果足够简单,我建议您使用 JSON 或求助于原生 pickle)...

此时,您已经完成了 subprocess 的一半工作模块正在这样做,您不妨将您的功能作为子流程启动并完成它。如果您必须经历这样的循环才能达到您想要的结果,那么很可能是您的原始设计有问题。在您的情况下 - 为什么不只向当前用户提供访问数据库的权限?用户将需要有能力切换到另一个用户,这样你就不会从中获得任何安全性 - 你只会让你的生活复杂化。

关于python - 如何使用python在linux中以不同用户身份运行部分代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51501029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com