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

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

我正在开发一个 LAMP Web 应用程序,并且在某个地方有一个预定的进程,该进程会不断创建一个shop在站点根目录中调用的文件夹。每次出现这种情况都会导致与应用程序中的重写规则发生冲突,这不好。

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

答案1

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

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

这种情况下你需要的用户空间程序是inotifywait(自带的inotify-tools,需要的话先安装)。


假设该目录shop位于/foo/bar目录中,让我们设置一个/foo/bar/shop创建监视,并rm在创建后立即监视:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • 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") }'

请注意,如果您正在查找名为的文件而不是目录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") }'

答案2

根据防止问题的字面意思回答文件夹要创建的特定名称。

touch shop

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

mkdir: cannot create directory ‘shop’: File exists

答案3

mkdir用...劫持系统调用怎么样LD_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

请注意,在此处理程序中,您可以记录想要创建此目录的进程的 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

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

export LD_PRELOAD=/path/to/test.so

答案4

创建一个指向不存在目录中不存在位置的符号链接。这有一些有趣的含义:

$ ln -s non-existent/foobar foo
$ ls -ln
total 0
lrwxrwxrwx 1 1000 1000 19 Okt  4 17:17 foo -> non-existent/foobar
$ mkdir foo
mkdir: cannot create directory ‘foo’: File exists
$ cat foo
cat: foo: No such file or directory
$ echo foo > foo
zsh: no such file or directory: foo
  1. mkdir、链接和其他文件将失败并显示EEXIST(文件存在)。
  2. 尝试打开路径进行读取、写入或追加将失败ENOENT(没有此类文件或目录)
  3. 在该位置上使用 stat(2)(不是 lstat(2) 或 stat(1))也会失败,并显示ENOENT. lstat 当然会返回有关符号链接的信息。

与此处提出的其他一些解决方案相比,这有两个优点:(a) 您不需要运行跟踪目录创建的服务;(b) 对于大多数命令来说,该名称似乎不存在。

您必须尝试一下,但我怀疑无论您有什么重写规则,它们都不使用 lstat 或其他非取消引用命令,从而导致它们失败。

相关内容