如何检测文件是否存在,而不会因权限问题而脱轨

How to detect if a file exists w/o getting derailed by permissions issues?

本文关键字:权限 问题 存在 何检测 检测 是否 文件      更新时间:2023-10-16
至少有

三种技术可以检测文件是否存在:

  1. 查询文件属性
  2. 使用具有特定文件名而不是搜索模式的 FindFile()
  3. 在阅读模式下打开文件并查看任何产生的错误

以上所有内容似乎都存在假阴性。 也就是说,我被告知该文件实际上不存在,因为它是由于网络上的 file-io 工作方式出现故障或由于文件权限问题。

我有一个客户可以看到资源管理器中存在一个文件,删除该文件,但如果他们尝试查看该文件,则会获得"访问被拒绝"。

我一直没有成功地复制这种确切的行为。 但是我可以创建的是文件存在的情况,但由于对它的权限限制,我无法在我的用户凭据下看到该文件夹中的文件。 也就是说,GetFileAttributes(),FindFile()和fopen()返回失败,即找不到该文件的文件(但是如果我在不同的帐户下查看同一文件夹 - 例如网络管理员,我可以看到该文件肯定存在)。

至于我的最终用户(或任何人)将如何在这种情况下结束对我来说是不透明的。 我没有具体的想法 - 也许是之前打开文件时电源故障,也许是某种网络故障导致文件句柄保持锁定到外部 PC 上的死进程,...? 我只是在编造东西,因为我不知道什么会导致这种情况出现。

但是,我真正没有的是查询Windows并知道"文件X是否存在"这一事实

的能力。

有谁知道一种技术可以诚实地回答这个问题,无论用户的权限如何(假设他们被允许查询文件夹本身的内容 - 我不是在要求未经授权的访问场景 - 只是一个"普通"用户 X 无法编辑文件 Y,但仍然想知道文件 Y 是否存在。


好吧 - 这越来越奇怪了。

使用任何文件检测技术都可以,只要我问两次。 第一次总是告诉我"不存在"。 Second+告诉我"是的,它在那里,但你无法打开它。

有问题的文件位于 Windows Server 2008 NTFS 驱动器上的共享文件夹中。 它共享给每个人完全控制。 我手动将"每个人都拒绝读取"ACL添加到文件中,以模拟我的客户问题。 所以我拒绝了读取,但没有其他访问权限,并且只访问文件,而不是共享或该文件所在的文件夹。

(我使用资源管理器进行此修改,而不是我自己的软件或命令行实用程序)。

我可以看到该文件存在于该服务器上的本地管理员帐户中。 我甚至看不到它存在于我的本地工作站中,在 Windows 7 下以标准用户身份登录,启用 UAC,非提升的资源管理器/应用程序。


看起来,如果文件的读取访问权限被明确拒绝,该文件将不再可见(除非该拒绝不适用,或者对于本地管理员,尽管拒绝ACL,它有一些后门方式查看文件)。

我尝试过FindFirstFile,GetAttributes,CreateFile,_taccess_s和PathFileExists。 在每种情况下,第一次尝试访问文件都指示"找不到文件",但连续第二次尝试会导致无错误(找到文件)。

我无法开始解释这些结果。 我认为此时我需要在本地运行所有测试,以从组合中删除网络文件共享。 这些结果(对我来说)并没有多大意义。


文件夹的 FLTMC 输出,来自服务器上的本地管理员帐户:

Filter Name                     Num Instances    Altitude    Frame
------------------------------  -------------  ------------  -----
aksdf                                   8       145900         0
luafv                                   1       135000         0

有一个名为 access 的 POSIX 函数可以执行此操作。 看起来有一个Windows等效_access:http://msdn.microsoft.com/en-us/library/1w06ktdy(v=vs.80).aspx

你有没有尝试过WinAPI调用CreateFile,第二个参数设置为0?以下是描述:http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx 和我指出的部分是:"如果此参数为零,则应用程序可以查询某些元数据,例如文件、目录或设备属性,而无需访问该文件或设备,即使GENERIC_READ访问将被拒绝。

如果权限设置为"您甚至不被允许查看此文件的名称"(例如,拒绝您访问它所在的目录),则任何"查看"该文件的能力,即使只是确认或否认其存在,都是一个明显的安全漏洞。

因此,我只能看到几种可能性。最明显的是使用管理员帐户搜索文件。这可能会惹恼用户,因为他们很可能需要输入该管理帐户的凭据才能使用它。对于无权访问管理员帐户的用户(大多数,您希望),它根本不起作用。

另一种可能性是找到并利用一个安全漏洞,让你做你想做的事,即使你真的不应该这样做。这(至少)同样有问题 - 几乎任何修补程序,Service Pack等都可能"堵塞"您正在利用的安全漏洞,并且您的代码将停止工作。同样,至少有一个合理的机会,某种反恶意软件可能会决定(或多或少正确)你的代码是顽皮的,并告诉用户它正在做坏事。

使用 shell 函数 PathFileExists

另一种方法是模仿 Delphi/BCB 中的 FileExists 功能,即使用FindFirstFile来获取文件的WIN32_FIND_DATA,从而检查它是否存在。

顺便说一句,你提到的情况完全是人为的。它涉及每个默认安装分配给非特权用户的SeChangeNotifyPrivilege。用户权限称为"绕过遍历检查"(在"安全设置"->"本地策略"-">用户权限分配"下的secpol.msc:)这意味着出于所有实际目的,如果您知道文件的路径和名称,您应该能够找出文件是否存在。


是的,杰瑞是对的,这是一个安全漏洞。但是一个经过计算的。特权("用户权限")正是:一种忽略某些权限问题的方法。这就是Windows中特权的真正目的。