在python中以超级用户身份打开文件

Ser*_*gio 5 python file-io

我必须打开一个系统文件并从中读取。这个文件通常只能被 root(超级用户)读取。我有办法向用户询问超级用户密码。我想使用此凭据打开文件并从中读取,而无需将整个程序作为超级用户进程运行。有没有办法以多平台的方式实现这一目标?

Ada*_*eld 4

由于权限在类 Unix 系统和 Windows 上的工作方式完全不同,因此您将需要具有特定于平台的代码。在任何情况下,您都需要将程序分解为两个单独的程序,其中一个以提升的权限运行,另一个以标准/降低的权限运行。

在类 Unix 系统(包括 Linux 和 Mac OS X)中,以提升的权限运行的可执行文件应该执行以下操作:

  1. 假设您以 root 身份运行并打开文件进行读取。由于您提到该文件非常大,因此您实际上并没有读取整个文件,而只是保留一个打开的文件描述符。如果打开失败,则打印错误消息并退出。
  2. 使用setreuid(2)setregid(2)将您的用户 ID 和组 ID 设置回非特权用户。
  3. 使用其中一个exec(3)函数来执行非特权可执行文件。
  4. 如果您想让它可以在不使用 的情况下运行该程序sudo,则将其设置为 root 所拥有,并使其成为带有 .set-user-ID 的可执行文件chown root the-program; chmod +s the-program

非特权程序现在将以普通权限运行,但当它启动时,它将有一个打开的文件描述符(文件描述符#3),可用于从特殊文件中读取。

对于 Windows,它类似但略有不同:

  1. 假设您以 root 身份运行并使用打开文件进行读取CreateFile。不要使用默认的安全属性——创建一个设置为的SECURITY_ATTRIBUTES结构,以便子进程继承该句柄。如果打开文件失败,则打印错误消息并退出。bInheritHandleTRUE
  2. 用于CreateProcess启动您的子进程。在命令行中传入上面的句柄(例如打印为数值);您也可以使用共享内存区域,但是对于这个问题来说,这比它的价值更麻烦。
  3. 将清单嵌入到此可执行文件中,并将requireAdministrator其设置为true。执行此操作后,当您运行该程序时,您将收到 UAC 提示,询问您是否允许该程序进行更改。

然后,子进程通过解析命令行来获取继承的句柄,然后它可以根据需要读取数据。

这种方法的一个问题是,当你继承一个句柄时,你必须使用低级系统调用(read(2)在 Unix 上,在 Windows 上)来读取它——你不能使用 C或 C++ReadFile等高级函数。 (好吧,Unix 有,但据我所知 Windows 上没有类似的东西)。fread(3)iostreamfdopen(3)

我相信您现在已经注意到,上面的所有内容都是用 C 编写的。在 Unix 中,这可以非常直接地转换为 Python,因为该os模块有很多好东西setreuid,例如exec*、 和fdopenctypes在 Windows 上,您也许可以使用模块和/或Pywin32来完成一些工作,但坚持使用 C 可能更容易。