C++ Linux:检查进程是否对C/C+中的文件具有读取权限+;

C++ Linux:检查进程是否对C/C+中的文件具有读取权限+;,c++,c,linux,pid,C++,C,Linux,Pid,假设我们有一些PID和绝对文件路径[不是一个符号链接,只是一个常规文件]-确定PID对此文件具有读取权限的最有效方法是什么?我只知道一种方法。首先,通过构建路径/proc/+PID来查找进程的UID和GID。例如/proc/4261。然后对该路径进行stat(),并获取其UID和GID。然后,stat()要检查读取权限的文件,并检查进程的UID/GID是否具有读取权限: (假设您已经在路径到\u proc中构建了“/proc/[PID]”路径) 请注意,代码并不完美。它不处理进程的用户实际上属于

假设我们有一些PID和绝对文件路径[不是一个符号链接,只是一个常规文件]-确定PID对此文件具有读取权限的最有效方法是什么?

我只知道一种方法。首先,通过构建路径
/proc/
+PID来查找进程的UID和GID。例如
/proc/4261
。然后对该路径进行stat(),并获取其UID和GID。然后,stat()要检查读取权限的文件,并检查进程的UID/GID是否具有读取权限:

(假设您已经在
路径到\u proc
中构建了“/proc/[PID]”路径)


请注意,代码并不完美。它不处理进程的用户实际上属于文件组而不是用户的主要组的可能性。要解决这个问题,您需要使用getgrouplist()(这意味着您需要首先将进程UID转换为包含实际用户名的字符串,然后将所有返回的组与文件的组进行比较,如果其中一个组匹配,请检查组读访问权限(s_IRGRP)。

打开文件。这真的是唯一知道的方法。涉及
stat(2)
的答案要求您编写代码来解释权限位,并将其与活动uid/gid和补充组进行比较。在任何情况下,它在一般情况下都是不完整的:像selinux或apparmor这样的LSM钩子也可以在传统Unix权限模型无法捕获的文件上实现权限模型。

这个问题的措辞让我相信它想要检查具有给定PID的不同进程的访问权限。@Angew Yeah,我发现太晚了。我完全修改了答案。@Eddy_Em这是
Man2统计数据
;-)@尼科斯,真的,谢谢<代码>man 2 stat比
man 3 stat
更详细。欢迎来到StackOverflow。你是真的在寻求最有效的方法,还是任何有效的方法都可以?如果效率是你的目标,你用什么来衡量效率?你绝对正确。“stat()”很好。一个漂亮、简单的“open()”——并检查错误状态——可以说更好。OP希望检查一些外部进程的访问。不是当前流程。那么该任务不可能完成,并且要求的格式不正确,很抱歉。我已经覆盖了LSM挂钩。但是,如果任务位于您的流程看不到的chroot中,该怎么办?该文件很可能是可读的,但您无法统计它以进行检查。同样,名称空间容器也是如此。或者该文件可能位于FUSE文件系统(比如sshfs)上,在该文件系统中,真正的权限是远程的,无法从本地环境得知。这就是行不通。
struct stat buf;

// Get UID and GID of the process.
stat(path_to_proc, &buf);
uid_t proc_uid = buf.st_uid;
gid_t proc_gid = buf.st_gid;

// Get UID and GID of the file.
stat(path_to_file_you_want_to_check, &buf);

// If the process owns the file, check if it has read access.
if (proc_uid == buf.st_uid && buf.st_mode & S_IRUSR) {
    // Yes, the process has read access.
}

// Check if the group of the process's UID matches the file's group
// and if so, check for read/write access.
else if (proc_gid == buf.st_gid && buf.st_mode & S_IRGRP) {
    // Yes, the process has read access.
}

// The process's UID is neither the owner of the file nor does its GID
// match the file's.  Check whether the file is world readable.
else if (buf.st_mode & S_IROTH) {
    // Yes, the process has read access.
}