我可以阻止创建特定名称的文件夹吗?

And*_*rew 16 linux directory directory-structure

我正在开发一个 LAMP 网络应用程序,并且在某处有一个计划进程,它不断创建一个shop在站点根目录中调用的文件夹。每次出现这种情况都会与应用程序中的重写规则发生冲突,这不好。

在我找到有问题的脚本之前,有没有办法防止shop在根目录中创建任何名为的文件夹?我知道我可以更改文件夹的权限以防止其内容被更改,但我还没有找到一种方法来防止创建特定名称的文件夹。

hee*_*ayl 31

您不能,因为创建目录的用户具有在父目录上写入的足够权限。

相反,您可以利用inotifyLinux 内核提供的系统调用系列来监视给定目录mv中目录的创建(和可选-ing)shop,如果已创建(或可选mv-ed)rm目录。

在这种情况下您需要的用户空间程序是inotifywait(随附inotify-tools,如果需要请先安装)。


假设目录shop将驻留在/foo/bar目录中,让我们为/foo/bar/shop创建设置监控,rm如果创建则立即:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
Run Code Online (Sandbox Code Playgroud)
  • inotifywait -qme create /foo/bar手表/foo/bar目录可能创建的,即手表任何任何文件/目录create事件

  • 如果创建,则awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'检查该文件是否恰好是一个目录且名称为shop( /,ISDIR shop$/),如果是,则检查rm该目录 ( system("rm -r -- /foo/bar/shop"))

您需要以对目录具有写权限的用户身份运行该命令才能从目录/foo/bar中删除shop


如果您也想监视mv-ing 操作,也可以添加监视moved_to事件:

inotifywait -qme create,moved_to /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
Run Code Online (Sandbox Code Playgroud)

请注意,如果您正在寻找一个名为 的文件,而不是目录shop

inotifywait -qme create /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'

inotifywait -qme create,moved_to /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'
Run Code Online (Sandbox Code Playgroud)

  • 此外,如果您使用 `inotifywait` 来执行此操作,那么触发器也可能能够使用 `ps -ef` 捕获进程 (2认同)

Mia*_*ati 30

根据防止创建某个名称的文件夹的问题,从字面上回答。

touch shop

如果存在同名文件,则无法创建目录

mkdir: cannot create directory ‘shop’: File exists

  • 在 Linux 系统上,使用 `chattr +i shop` 使其不可变。在不可变标志被移除之前,它甚至不能被重命名/删除。 (9认同)
  • 这*可能还不够*。mkdir 可能做不到,但可以做到。不过,这是一个很好的第一次尝试。 (6认同)

Nyk*_*kin 5

mkdirLD_PRELOAD...劫持系统调用怎么样?

$ ls
test.c
$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) return 1;

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test  test.c  test.so
Run Code Online (Sandbox Code Playgroud)

请注意,在此处理程序中,您可以记录要创建此目录的进程的 PID:

$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) {
        FILE* fp = fopen("/tmp/log.txt", "w");
        fprintf(fp, "PID of evil script: %d\n", (int)getpid());
        fclose(fp);
    }

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt 
PID of evil script: 8706
Run Code Online (Sandbox Code Playgroud)

您需要将它放在~/.bashrc根目录(或运行您的应用程序的任何人)中以确保将使用它:

export LD_PRELOAD=/path/to/test.so
Run Code Online (Sandbox Code Playgroud)

  • 它正在使用手提箱核武器打开一罐豆子。但是,嘿,至少它们会被煮熟... (5认同)
  • 这不应该有一个downvote,这是一个解决方案和一个很好的解决方案 (2认同)
  • @cat:我不同意。像这样的“LD_PRELOAD”黑客基本上总是错误的,除非你知道你在做什么,否则他们可以**严重**通过破坏你加载它们的程序的属性,比如你的函数的异步信号安全”重新更换。 (2认同)
  • 如果错误代码直接调用系统调用,而不是通过 libc,这也不起作用。或者如果坏代码是静态链接的。 (2认同)