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

5 投票
4 回答
13293 浏览
提问于 2025-04-17 01:51

我需要打开一个系统文件并从中读取内容。这个文件通常只有超级用户(也就是系统管理员)才能读取。我有办法向用户请求超级用户的密码。我想用这个密码来打开文件并读取内容,而不想让我的整个程序都以超级用户的身份运行。有没有什么方法可以在不同平台上实现这个目标?

4 个回答

3

我会把这个程序分成两部分。

  1. 第一部分负责打开文件和访问内容。它可以假设自己已经获得了所需的权限。
  2. 第二部分处理其他不需要特殊权限的内容。

在配置中添加一个条目,描述如何使用 execsubprocess 来执行需要额外权限的命令。比如:

access_special_file: sudo access_special_file

或者

access_special_file: runas /user:AccountWithPrivs access_special_file

这样可以把一些关于提升权限的系统细节交给系统的命令行,这样可能会有更方便的方法来获取你需要的权限。

4

你所寻找的东西叫做权限提升,这个过程很大程度上取决于你使用的平台。一般来说,你的程序需要以超级用户的身份运行一部分代码。在Unix系统上,比如说,你可以使用 sudo 来读取文件的内容。

不过正如之前提到的,这实际上是依赖于你所使用的系统。

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. 假设你是以管理员身份运行,使用 CreateFile 打开文件进行读取。不要使用默认的安全属性,而是创建一个 SECURITY_ATTRIBUTES 结构,将 bInheritHandle 设置为 TRUE,这样句柄就可以被子进程继承。如果打开文件失败,打印错误信息并退出。
  2. 使用 CreateProcess 启动你的子进程。在命令行中传入上面的句柄(例如,作为数字值打印出来);你也可以 使用共享内存区域,但对于这个问题来说,这样做麻烦得不值得。
  3. 在这个可执行文件中嵌入一个清单,将 requireAdministrator 设置为 true。这样,当你运行程序时,会弹出一个用户账户控制(UAC)提示,询问你是否允许程序进行更改。

子进程会通过解析命令行来获取继承的句柄,然后可以随意读取数据。

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

正如你现在可能已经注意到的,以上所有内容都是用C语言写的。在Unix中,这些内容可以很简单地转换成Python,因为 os模块 提供了很多好用的功能,比如 setreuidexec*fdopen。在Windows上,你可能可以用 ctypes 模块和/或 Pywin32 来做一些这些事情,但可能还是用C更简单。

撰写回答