【问题标题】:How to check if a file can be created inside given directory on MS XP/Vista?如何检查是否可以在 MS XP/Vista 的给定目录中创建文件?
【发布时间】:2010-10-01 19:14:39
【问题描述】:

我有一个在用户指定目录中创建文件的代码。用户可以指向一个他不能在其中创建文件的目录,但他可以重命名它。

我为测试目的创建了目录,我们称之为C:\foo

我对@9​​87654322@ 有以下权限:

  • 遍历目录/执行文件
  • 删除子文件夹和文件
  • 正在删除
  • 读取权限
  • 更改权限
  • 取得所有权

我对@9​​87654323@没有以下任何权限:

  • 完全控制
  • 文件创建
  • 文件夹创建

到目前为止,我已经尝试了以下方法:


os.access('C:\foo', os.W_OK) == True

st = os.stat('C:\foo')
模式 = st[stat.ST_MODE]
模式 & stat.S_IWRITE == 真

我相信这是因为我可以重命名文件夹,所以它对我来说是可变的。但它的内容 - 不是。

有谁知道如果当前用户有权在该目录中创建文件,我该如何编写代码来检查给定目录?

简而言之 - 我想检查当前用户是否具有给定文件夹名称的文件创建文件夹创建权限。

编辑:对此类代码的需求源于“Certified for Windows Vista”程序的第 3 号测试用例,其中指出:

  1. 应用程序不得允许最低权限用户将任何文件保存到 Windows 系统目录以通过此测试用例。

这是否应该理解为“应​​用程序可能会尝试将文件保存在 Windows 系统目录中,但不应该在失败时崩溃?”或者更确切地说“应用程序必须在尝试保存文件之前执行安全检查?”

我是否应该仅仅因为 Windows Vista 本身不允许最小特权用户将任何文件保存在 %WINDIR% 中而停止打扰?

【问题讨论】:

    标签: python windows winapi windows-vista permissions


    【解决方案1】:

    我最近编写了一个应用程序来通过一组测试以从 Microsoft 获得 ISV 状态,并且我还添加了该条件。 我理解的方式是,如果用户是最低权限,那么他将无权写入系统文件夹。所以我按照 Ishmaeel 描述的方式解决了这个问题。我尝试创建文件并捕获异常,然后通知用户他无权将文件写入该目录。

    据我了解,最低权限用户将没有必要的权限来写入这些文件夹,如果他有,那么他不是最低权限用户。

    我是否应该仅仅因为 Windows Vista 本身不允许最低权限用户将任何文件保存在 %WINDIR% 中而停止打扰?

    在我看来?是的。

    【讨论】:

    • 谢谢。我会听从你和 Ishmaeels 的建议。
    【解决方案2】:

    我不会浪费时间和 LOC 来检查权限。在 Windows 中创建文件的终极测试是创建本身。其他因素可能会发挥作用(例如具有相同名称的现有文件(或更糟的是文件夹)、磁盘空间、后台进程。这些条件甚至可能在您进行初始检查和您实际尝试创建文件。

    所以,如果我有这样的场景,我会设计我的方法以在失败的情况下不丢失任何数据,继续尝试创建我的文件,并为用户提供更改所选目录的选项如果创建失败,请重试。

    【讨论】:

    • 目前应用程序在这种情况下不会崩溃,只是显示一个操作失败的弹出窗口。但我真正需要的是通过“Windows Vista 认证”测试 - 请参阅已编辑的问题。
    • 我相信测试用例意味着应用程序不应包含权限提升漏洞或试图规避标准安全性以允许所述操作。除此之外,目录安全应该是操作系统的责任。
    【解决方案3】:

    我同意其他答案,即尝试创建文件并捕获异常。

    然而,在 Vista 上要小心 UAC!参见例如"Why does my application allow me to save files to the Windows and System32 folders in Vista?":为了支持旧应用程序,Vista 将“假装”创建文件,而实际上它是在当前用户配置文件下的所谓虚拟存储中创建文件。

    为避免这种情况,您必须通过在 .exe 的清单中包含适当的命令来明确告诉 Vista 您不需要管理权限,请参阅上面链接的问题。

    【讨论】:

    • 感谢您的警告,但有问题的应用程序已经将所需的执行级别设置为“asInvoker”,所以我不应该碰到 UAC :-)
    【解决方案4】:
    import os
    import tempfile
    
    def can_create_file(folder_path):
        try:
            tempfile.TemporaryFile(dir=folder_path)
            return True
        except OSError:
            return False
    
    def can_create_folder(folder_path):
        try:
            name = tempfile.mkdtemp(dir=folder_path)
            os.rmdir(name)
            return True
        except OSError:
            return False
    

    【讨论】:

    • 如果用户无权删除目录但有权创建目录,您的 can_create_folder() 将失败。你不应该捕获一个 IOError 而不是 OSError 吗?我收到带有 errno:13 的 IOError。否则很好,但无论如何我必须在创建实际文件时捕获 IOError(竞争条件)。
    • 请注意 Python 3.3 引发了 PermissionError。因此,最好对其进行一次测试,看看它会为您的 Python 版本引发什么样的异常。
    • 我一般把EnvironmentError抓成IOErrorOSErrorWindowsError都是来源于它
    猜你喜欢
    • 2015-02-20
    • 2019-08-28
    • 2010-11-06
    • 2017-12-16
    • 2019-12-03
    • 2010-09-23
    • 2015-02-05
    • 2016-02-01
    • 2010-11-04
    相关资源
    最近更新 更多