我是 Fuse 的新手。我已通过以下命令安装了 Fuse。
/home/bin/fusexmp /mnt/fuse -o default_permissions -o allow_other -o nonempty -o hard_remove -d
现在,如果我以“测试”用户身份登录并尝试创建一个名为“testfile”的文件。
test@11540302:/registration> touch testfile
touch: setting times of `testfile': Permission denied
Strace 输出:
uname({sys="Linux", node="11540302", ...}) = 0
brk(0) = 0x8055000
brk(0x8076000) = 0x8076000
open("testfile", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0666) = 3
dup2(3, 0) = 0
close(3) = 0
utimensat(0, NULL, NULL, 0) = -1 EACCES (Permission denied)
close(0) = 0
但“testfile”创建成功,所有者为根用户,
-rw-r--r-- 1 root trusted 0 Jan 19 13:51 testfile
我可以理解 fuse 应用程序在 root 级别运行,文件创建以 root 所有者的身份进行。因此,测试用户无法对“testfile”执行任何操作。
我的问题:
1. 既然我在挂载时已经授予了“allow_other”,为什么测试用户无法拥有访问“testfile”的权限?
2. 以“test”用户身份登录并尝试创建“testfile”后,为什么文件所有者是“root”,而不是“test”。即使在挂载期间提供“default_permission”,也会出现这种情况。
如果我的理解有误,请纠正我。
答案1
好的,让我澄清一下:您没有“挂载 fuse”,您使用的是示例程序fusexmp
,这是一个非常简单的 fuse 程序,它只是将所有操作传递给标准 Linux 库调用。这只是一个示例程序,而且是一个非常无聊的程序。
您没有说明以哪个用户身份执行了此挂载操作,但我假设您以该用户身份执行了此操作root
(因为否则allow_other
将无法正常工作,并且不会使用testfile
所有者创建root
)。请注意,原则上您可以以任何用户身份挂载 FUSE 文件系统。
因此,当test
用户执行时touch
,他首先在 fuse 挂载的文件系统上打开文件。由于您使用了default_permissions
,系统会检查用户是否test
被允许在此特定目录中创建文件(显然成功了),然后让fusexmp
创建文件。当fusexmp
运行时root
,此文件被创建为root
。
接下来,touch
想要设置日期。由于您使用了default_permissions
,系统会检查用户是否test
被允许在此特定文件上设置日期。事实并非如此,因此系统会因权限错误而中止,无论程序是否fusexmp
真的能够设置日期(如果以 root 身份运行,它确实可以设置)。
我仍然不确定这个练习的要点:你以一种不寻常的方式使用了一个示例程序,然后对结果感到疑惑。如果你给出default_permissions
,那么你还应该确保你的用户空间程序创建的文件具有正确的所有者等(事实fusexmp
并非如此)。
如果你想从用户的角度理解 fuse 文件系统,我建议你尝试一些真实的例子,比如SSHFS或者编写自己的保险丝程序并自行处理权限等。
答案2
我找到了这个问题的解决方案。
解决方案:
正如@dirkt 所说,我们需要自己处理权限。
获取调用者uid和gid的代码:
fuse_get_context()->uid;
fuse_get_context()->gid;
通过 fuse API 创建时,获取调用者用户 ID 和组 ID 并设置文件/目录的所有权。
总有进步的空间。如果我说得不对,请纠正我。
感谢 dirkt 的解释。