我希望能够让他们留在 GUI 中,并出现一个弹出窗口,上面写着“呃,你需要 root 才能做到这一点。请输入你的密码。”
这正是 MacOS API 的 AuthorizationExecuteWithPrivileges() 函数的创建目的。
你可以直接用python的ctypes调用AuthorizationExecuteWithPrivileges()。
例如,假设您的父脚本以您的普通非 root 用户身份运行。如果您尝试只运行setuid(0),那么它将失败
PermissionError: [Errno 1] Operation not permitted
相反,让我们创建另一个名为root_child.py 的脚本,我们将使用AuthorizationExecuteWithPrivileges() 以root 身份执行它
孩子(root_child.py)
#!/usr/bin/env python3
import os
if __name__ == "__main__":
try:
os.setuid(9)
print( "I am root!" )
except Exception as e:
print( "I am not root :'(" )
父级 (spawn_root.py)
我们可以从我们的非root脚本spawn_root.py以root身份执行上述root_child.py脚本:
import sys, ctypes, struct
import ctypes.util
from ctypes import byref
# import some C libraries for interacting via ctypes with the MacOS API
libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c"))
# https://developer.apple.com/documentation/security
sec = ctypes.cdll.LoadLibrary(ctypes.util.find_library("Security"))
kAuthorizationFlagDefaults = 0
auth = ctypes.c_void_p()
r_auth = byref(auth)
sec.AuthorizationCreate(None,None,kAuthorizationFlagDefaults,r_auth)
exe = [sys.executable,"root_child.py"]
args = (ctypes.c_char_p * len(exe))()
for i,arg in enumerate(exe[1:]):
args[i] = arg.encode('utf8')
io = ctypes.c_void_p()
print( "running root_child.py")
err = sec.AuthorizationExecuteWithPrivileges(auth,exe[0].encode('utf8'),0,args,byref(io))
print( "err:|" +str(err)+ "|" )
print( "root_child.py executed!")