8

我已经成功地分别使用stat()&access()来确定用户是否具有对目录的读或读/写访问权限。

我的问题是: - 有没有首选的方法?我看到很多使用 的示例stat,但就我的目的而言,访问似乎更轻量级并且服务于目的。
- 是否有任何问题(例如 - 安全性)w/一个或另一个?- 我的方法有什么问题吗?

这是一些伪代码(从内存重新创建,无需编译):

       // Using access():
    bool readAccessPermission = false; 
    bool writeAccessPermission = false;

    if (mode == 'r'){
            if (access(directory, R_OK) == 0)
                    readAccessPermission = true;                        
    }
    else{
            if (access(directory, R_OK && W_OK) == 0)
                    readAccessPermission = true;
                    writeAccessPermission = true;
    }


    // vs. using stat function
    // assume I already called stat(directory) and have the object


    bool readAccessPermission = false; 
    bool writeAccessPermission = false;

    var retmode = ((stats.mode) & (0777));

    if (modeString == 'r'){ 
        if ((retmode) & (consts.S_IRUSR)){
            readAccessPermission = false; 
        }    
    } 
    else{ 
        if ((retmode) & (consts.S_IRUSR)){
            readAccessPermission = true; 

            if ((retmode) & consts.S_IWUSR)){               
                writeAccessPermission = true; 
            }
        }
    }
4

3 回答 3

9

两者都可以满足您的需求。access()如果你不打算对你填充的统计结构做任何事情,它是一个更干净的包装器。

请注意,这样做时您正在创造一场比赛。stat()/access()在调用和实际尝试使用目录时,权限可能会发生变化。地狱,那个目录甚至可以在那个时候被删除和重新创建。

最好尝试打开您需要的内容并检查EPERM. 检查stat()access()不会保证后续操作不会返回 EPERM。

于 2011-08-17T05:04:21.083 回答
4

在简单的情况下,对于我们的问题,两者在功能上是等效的。此外,access()由于要获取相同的数据结构(inode),速度不会快得多。

但是,如果系统上使用了访问控制列表 ( ACL ),则访问将处理这些列表,而您无法使用stat数据检查 ACL。

于 2011-08-17T09:13:20.003 回答
1

这两个代码片段不相同,会产生截然不同的结果。

首先,您的 stat 调用仅检查所有者的权限位。如果运行此代码的用户不拥有相关文件,则这不是要检查的正确位集。

其次,即使我们假设调用用户是所有者,我们也需要弄清楚我们所说的“调用用户”是什么意思。对于open(2)和它的朋友来说,主叫用户是返回的号码geteuid(2),即有效用户ID。这是 open 用来确定是否允许打开文件的方法。就access(2)目前而言,主叫用户是返回的号码getuid(2),也就是真实的用户ID。这是访问用来确定是否报告成功的内容。真实有效的 UID 可能会有所不同,尤其是在启用 setuid 位运行二进制文件时,或者当程序员正在做一些特别聪明的事情时(恕我直言,这可能是不明智的)。

(同时,stat()不关心调用用户的一种或另一种方式,除非它需要对包含目录的执行权限才能完成其工作。为此,它会检查 EUID)。

最后,正如多个答案中所指出的那样,这两个代码片段都可能容易受到TOCTTOU错误的影响,具体取决于您对结果的处理方式。总而言之,确定是否允许某个操作的最安全方法是尝试该操作并检查它是否失败。

于 2016-11-11T00:31:36.300 回答