【问题标题】:Pass root privilege to "os" commands in Python将root权限传递给Python中的“os”命令
【发布时间】:2019-01-07 00:33:35
【问题描述】:

我正在向 PyQt5 应用程序添加功能。这项新功能涉及复制、链接和删除可能在受保护目录中的文件(和链接),因此os.symlinkshutil.copyfile 等命令将失败。

当然,主应用程序不是以 root 权限运行的(要求用户这样做是不可能的),所以我需要一个解决方法。

首先当然是将关键代码包装在 try/except 块中并调查任何异常。如果事实证明缺少 root 权限是我会在对话框中询问密码的问题(大概只要当前对话框处于活动状态就存储密码)。

但我不确定如何使用 root 密码重复步骤 。我强烈希望在 Python 域中执行此操作(或者 Qt 是否为文件操作提供了一些支持?我敢打赌它确实提供了,但我找不到它)。我认为应该可以通过在 shell 命令中执行文件操作并以某种方式将密码传递给该命令,但由于 Python 和 PyQt 旨在保护程序员免受操作系统差异的复杂性影响,我宁愿避免使用这种方法。

一些伪代码应该可以清楚地说明问题:

def my_copy(source, dest):
    try:
        os.path.symlink(source, dest)
    except: # check for permission problem:
        # use dialog to ask for password
        # repeat the symlink procedure with password

【问题讨论】:

  • 在对话框中询问密码不会有帮助,因为大多数操作系统不会让你用它做任何有用的事情,聪明的用户不会想把它交给你以不受保护地存储记忆。您需要使用 libpam、授权服务或我忘记名称的 Windows API 来要求用户进行身份验证——或者您需要创建一个 suid 帮助程序或一个守护程序或 Windows 服务,您可以通过某些 IPC 与之通信,因此用户可以在安装时授予权限。
  • 或者,您也可以让您的应用以 root 身份启动,然后派生一个非 root 进程来运行 GUI,同时使用 root 进程执行 root 工作。
  • 我不认为要求用户以 root 身份启动整个程序是一个可以接受的想法。也许我不得不诉诸于简单地通知用户权限问题,并告诉他们如何在应用程序之外手动解决任务。

标签: python qt file-permissions privilege-elevation


【解决方案1】:

使用计数器将 try/except 代码包装在一个循环中:

def my_copy(source, dest):
    for attempts in [1, 2]:
        try:
            os.path.symlink(source, dest)
            # we succeeded, so don't try any more
            break
        except: # check for permission problem:
            if attempts == 1:
                # use dialog to ask for password
                # repeat the symlink procedure with password
            else:
                 # we already tried as root, and failed again
                 break

【讨论】:

  • 对不起,虽然这是部分问题的一个很好的例子,但它并不是我真正要问的(可能问题不够清楚)。我的问题不是控制结构,而是如何将密码传递给文件操作。尽管如此,我还是赞成,因为它会为人们找到这个页面服务。
【解决方案2】:

您在这里尝试做的事情在大多数现代操作系统上基本上是不可能的,而且有充分的理由。

想象一个典型的 macOS 或 Windows 用户希望能够通过使用指纹读取器而不是输入密码来进行身份验证。或者是盲人用户。或者有人对您的应用程序以纯文本形式将密码存储在非内核内存中的 Python 字符串中(更不用说在其事件可以被任何进程挂钩的 Windows 对话框中)抱有合理的偏执。这就是为什么现代平台会配备像libPAM/XSSOAuthorization Services 这样的框架。等等

Windows 和 POSIX 甚至 macOS 和 Linux 之间的权限提升工作方式如此不同,更不用说发展如此迅速,据我所知,没有跨平台框架可以做到这一点。

事实上,大多数系统一开始就不鼓励应用驱动的权限提升。在 Windows 上,您经常要求操作系统以提升的权限运行帮助应用程序(然后操作系统将应用适当的策略并决定请求什么)。在 macOS 上,您通常编写一个 LaunchServices 守护程序,您在安装时(使用特殊的安装程序 API)而不是运行时获得许可。对于传统的非服务器型 POSIX 应用程序,您通常会执行类似的操作,但您可以在安装时创建一个 setuid 帮助程序,因为安装以 root 身份运行。对于传统的 POSIX 服务器,您通常以 root 身份启动,然后在 fork 并执行类似的辅助守护程序后删除 privs。

如果所有这些看起来比你想要处理的工作要多得多……好吧,老实说,这可能是本意。操作系统设计人员不希望应用程序设计人员引入安全漏洞,因此他们确保您必须了解平台想要什么以及如何使用它而不是反对它,然后您才能尝试执行以下操作移动您无权访问的文件。

【讨论】:

  • 谢谢,这是一个很好的解释 not 为我提供了实现我所要求的步骤。我模糊地意识到这一点(至少在没有为 Python 或 Qt 找到合适的本地工具之后),但这让我更愿意只向用户提供他们必须在外部进行的反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多