我有一个通过 Samba 共享的目录。我希望用户能够创建/修改/删除文件,但不能创建/删除目录。我还没有找到办法做到这一点。也许使用 SELinux?但如何呢?
答案1
优雅的方式是使用理查克斯。但这还不是内核的正式部分,因此可能很难使用。
一个简单的解决方法是使用 samba 参数directory mask
并使force directory security mode
新创建的目录对用户无用(无法访问),以便他们学会不要创建目录。
有趣的(并且可移植的!)方法是创建如此多的(不可见的)子目录,以达到文件系统的子目录限制。如果需要新的子目录,管理员只需重命名其中一个即可。
答案2
您可以做的是使用 FUSE 文件系统,例如与禁用和系统调用的劫持者bindfs
结合使用。就像创建一个文件一样:LD_PRELOAD
mkdir
rmdir
wrapper.c
#include <errno.h>
int mkdir() { errno = EPERM; return -1; }
int rmdir() { errno = EPERM; return -1; }
编译它:
gcc -fPIC -shared -o wrapper.so wrapper.c
并运行:
LD_PRELOAD=$PWD/wrapper.so bindfs the-dir the-dir
它将安装the-dir
在自身之上,但无法创建或删除目录。
你仍然可以改名不过目录。
答案3
在 Linux 和 ext4 文件系统上,防止创建目录(而不是其他类型的文件)的一种巧妙方法是依靠新创建的目录继承以下事实:默认 ACL 条目从其父目录(除了相应的非默认 ACL 条目之外),而文件仅被分配相应的非默认 ACL 条目和至少在 ext4 上,每个 inode 只有有限的空间来存储这些 ACL 条目。
因此,如果您用以下内容填充目录空间默认 ACL 条目到了极限,您仍然可以在其中创建文件,但不能创建目录,因为系统将无法创建默认和非默认 ACL 条目:
$ i=50000; while setfacl -m "d:u:${i}:-" .; do i=$((i + 1)); done
setfacl: .: No space left on device
(该循环的退出条件是 setfacl 失败时(此处在 ENOSPC 上,因为无法添加更多 ACL 条目))。
$ getfacl . | grep -c default:
507
添加了 507 个默认 ACL 条目(有效拒绝用户 50000 到 50506 访问其中创建的任何文件和目录)。
$ touch file
$ mkdir dir
mkdir: cannot create directory ‘dir’: No space left on device
$ ls -l
total 4
-rw-r--r--+ 1 chazelas chazelas 0 Nov 27 13:35 file
甚至root
无法在那里创建目录:
$ sudo mkdir x
mkdir: cannot create directory ‘x’: No space left on device
但这并不能阻止用户删除或重命名其中的目录(如果在添加这些默认 ACL 之前已经创建了一些目录)。