Posso impedir a criação de uma pasta com um determinado nome?

Posso impedir a criação de uma pasta com um determinado nome?

Estou trabalhando em um aplicativo da web LAMP e há um processo agendado em algum lugar que continua criando uma pasta chamada shopna raiz do site. Cada vez que isso aparece, causa conflitos com regras de reescrita no aplicativo, o que não é bom.

Até encontrar o script incorreto, existe uma maneira de impedir que qualquer pasta chamada shopseja criada na raiz? Eu sei que posso alterar as permissões de uma pasta para evitar que seu conteúdo seja alterado, mas não encontrei uma maneira de impedir a criação de uma pasta com um determinado nome.

Responder1

Você não pode, pois o usuário que cria o diretório tem permissão suficiente para escrever no diretório pai.

Em vez disso, você pode aproveitar a inotifyfamília de chamadas do sistema fornecidas pelo kernel do Linux, para observar a criação (e opcionalmente mv-ing) do diretório shopno diretório fornecido, se criado (ou opcionalmente mv-ed), rmo diretório.

O programa de espaço do usuário que você precisa neste caso é inotifywait(vem com inotify-tools, instale-o primeiro, se necessário).


Supondo que o diretório shopreside no /foo/bardiretório, vamos definir um monitoramento para /foo/bar/shopcriação e rminstantaneamente se for criado:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/barobserva /foo/baro diretório para qualquer arquivo/diretório que possa ser criado, ou seja, observa qualquer createevento

  • Se criado, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'verifica se o arquivo é um diretório e o nome é shop( /,ISDIR shop$/), em caso afirmativo, rmo diretório ( system("rm -r -- /foo/bar/shop"))

Você precisa executar o comando como um usuário que tenha permissão de gravação no diretório /foo/barpara remoção shopdo diretório.


Se você quiser monitorar mvtambém as operações -ing, adicione watch for moved_toevent também:

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

Apenas para observar, se você estiver procurando por um arquivo, não um diretório, chamado 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") }'

Responder2

Para responder literalmente com base na questão de prevenir umapastade um determinado nome a ser criado.

touch shop

Você não pode criar um diretório se existir um arquivo com nome idêntico

mkdir: cannot create directory ‘shop’: File exists

Responder3

Que tal sequestrar mkdiro syscall com 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

Observe que dentro deste manipulador você pode registrar o PID do processo que deseja criar este diretório:

$ 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

Você precisa colocar isso no ~/.bashrcroot (ou em quem está executando seu aplicativo) para garantir que isso será usado:

export LD_PRELOAD=/path/to/test.so

Responder4

Crie um link simbólico apontando para um local inexistente dentro de um diretório inexistente. Isso tem algumas implicações divertidas:

$ 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, link e outros falharão com EEXIST(Arquivo existe).
  2. A tentativa de abrir o caminho para leitura, gravação ou acréscimo falhará com ENOENT(Nenhum arquivo ou diretório)
  3. Usar stat(2) (não lstat(2) ou stat(1)) no local também falha com ENOENT. É claro que lstat retornará as informações sobre o link simbólico.

Isso tem duas vantagens sobre algumas das outras soluções propostas aqui: (a) você não precisa de um serviço em execução que rastreie a criação do diretório e (b) o nome parece não existir para a maioria dos comandos.

Você terá que tentar, mas suspeito que quaisquer que sejam as regras de reescrita que você tenha, elas não usam lstat ou outros comandos sem desreferência, fazendo com que falhem.

informação relacionada