场景是这样的 - 我有一个可能无法以 root 身份运行的命令行程序,部分要求是警告其他用户是否对某些文件夹/文件具有写权限
例如
- 我以非 root 用户 A 身份运行
- 我想得到问题的答案:“用户B是否有对文件夹F的写权限”
所以我的问题是
- 甚至可以以 root 用户身份执行吗?如果是这样怎么办?
- 有没有办法以非 root 用户身份执行此操作?
答案1
一般来说,了解用户 B 是否可以写入目录 D 的唯一方法是用户 B 尝试写入目录 D。
因此,作为 root,您可以su
以该用户身份尝试一下。尽管这可能不是 100% 准确,因为用户登录并输入密码可能会改变一些事情(例如,pam 模块可能会根据用户的密码设置加密密钥)。
几乎和 root 一样准确,您可以su
向用户使用access(2)
系统调用或类似的命令。如果您使用 ,这可能就是 shell 所做的事情test -w
,并且也是如此/usr/bin/test
。尽管正如联机帮助页所警告的那样,在 NFSv2 上,实际的检查是由服务器完成的,但access
系统调用的测试是在本地完成的,因此可能是错误的。类似地,FUSE 文件系统也可以做同样的事情。
(access(2)
联机帮助页还提到了一个竞争条件,这对于您所做的事情至关重要:B 对 D 的权限可能会在您检查时和 B 实际尝试写入 D 之间发生变化。)
除此之外,您必须决定您愿意接受的准确度:
- 您可以统计目录,并检查用户和组(如其他几个答案所示)
- 您还可以检查目录上的 ACL。
但即使你这样做了,以下情况也会让你陷入困境:
- 通过 NFS 和各种其他网络文件系统,服务器决定是否允许访问。它可以根据自己喜欢的任何方式做出决定。例如,考虑各种南瓜 NFS 导出选项。
- 权限检查实际上是由文件系统完成的;非 Unix 文件系统可能会给出意想不到的答案(Unix 用户如何映射到 NTFS 的 SID?)。所有的赌注都与例如 FUSE 文件系统有关。
答案2
“用户B是否有文件夹F的写权限”
用户A能否确定这一点取决于A对文件夹F的访问权限。例如,如果F是/home/B/foo/bar
并且A无法读取/home/B/foo
,那么A甚至无法检查F是否存在,更不用说对其设置了哪些权限。
假设 A 确实具有对 F 的读取访问权限,因此可以对其进行stat()
1获取权限,下一步是确定 B 是否是所有者或在组中。对于后者,您可以使用getgrent()
(本机 C - 它有一个手册页;注意这不带参数,而是/etc/group
一次迭代一个条目)获取组中的用户列表,该列表返回一个struct group
:
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
最后一个字段gr_mem
是一个字符串数组,其中包含用户名列表(该列表以NULL
指针终止)。与文件模式相结合,足以告诉您特定用户是否具有写入权限。
getgrent()
使用, 打印包含 ID 和成员的组列表的示例:
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
// std=c99
int main (void) {
struct group *ent = getgrent();
while (ent) {
printf (
"%s GID %d\n",
ent->gr_name,
ent->gr_gid
);
int i = 0;
char *p = ent->gr_mem[i];
while (p) {
printf("\t%s\n", p);
p = ent->gr_mem[++i];
}
ent = getgrent();
}
return 0;
}
访问/etc/group
(和使用getgrent()
)不需要特权。
1 您没有提及您正在使用什么语言,但希望“stat”是相当不可知的。 getgrent()
大部分也应该被移植,但是移植到什么取决于语言。
答案3
回答第一个问题(以root身份运行):
是 ->su - userB -c '<command as userB to touch file in folderF>'
回答第二个问题:
可能 -> 仅当非用户与 userB 位于同一组并尝试触摸folderF 中的文件时
答案4
如果我理解正确的话,您需要检查特定文件夹的用户权限。
所以基本上首先对用户运行 groups 命令。
groups userB
上面的命令将列出所属的所有组userB
。在那之后,
使用stat
命令查找八进制权限文件夹如下。
stat -c "%a %n" /some-folder
上面的命令将返回该特定的八进制权限文件夹/文件。
例如,如果上面的命令返回第775章,这意味着user
并且group
可以完全rwx
访问文件夹 others
可以r-x
访问文件夹。
确定组用户A以及使用groups userA
命令,如果两者都用户A和用户B属于同一组则意味着用户B有写文件的权限。