Posso impedir que uma pasta de um certo nome seja criada?

16

Estou trabalhando em um aplicativo da Web LAMP e há um processo agendado em algum lugar que cria uma pasta chamada shop na raiz do site. Toda vez que isso aparece, causa conflitos com regras de reescrita no aplicativo, não é bom.

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

    
por Andrew 03.10.2016 / 05:36

5 respostas

30

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

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

O programa userspace que você precisa neste caso é inotifywait (vem com inotify-tools , instale primeiro se necessário).

Assumindo que o diretório shop estaria residindo no diretório /foo/bar , vamos definir um monitoramento para /foo/bar/shop creation e rm instantaneamente se criado:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/bar watches /foo/bar diretório para qualquer arquivo / diretório que possa ser criado, por exemplo, observe qualquer evento create

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

Você precisa executar o comando como um usuário que possui permissão de gravação no diretório /foo/bar para remoção de shop do diretório.

Se você quiser monitorar também as operações mv -ing, adicione watch também ao evento moved_to :

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") }'
    
por 03.10.2016 / 06:08
30

Para responder literalmente com base na questão de impedir que uma pasta de um determinado nome seja criada.

touch shop

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

mkdir: cannot create directory ‘shop’: File exists

    
por 03.10.2016 / 07:22
4

Que tal seqüestrar mkdir 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 desse 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 em ~/.bashrc da raiz (ou quem está executando o aplicativo) para garantir que isso seja usado:

export LD_PRELOAD=/path/to/test.so
    
por 03.10.2016 / 14:40
3

(Eu teria comentado a resposta da Miati, mas não me lembro da minha conta antiga e não tenho reputação suficiente sobre essa nova ...)

Você pode bloquear a criação criando um arquivo e, em seguida, alterando os atributos do arquivo.

$ sudo touch shop
$ sudo chattr +i shop

Então, qualquer tentativa de fazer qualquer coisa com esse arquivo será bloqueada - mesmo que o usuário se torne root.

$ rm shop
rm: remove write-protected regular empty file ‘shop’? y
rm: cannot remove ‘shop’: Operation not permitted
$ sudo rm shop
rm: cannot remove ‘shop’: Operation not permitted
    
por 03.10.2016 / 18:55
2

Crie um link simbólico apontando para um local inexistente dentro de um diretório não existente. 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 (o arquivo existe).
  2. A tentativa de abrir o caminho para leitura, gravação ou anexação falhará com ENOENT (Nenhum arquivo ou diretório)
  3. O uso de stat (2) (não lstat (2) ou stat (1)) no local também falha com ENOENT . O lstat, é claro, retornará as informações sobre o link simbólico.

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

Você terá que tentar, mas suspeito que, independentemente das regras de reescrita que você tenha, elas não usam lstat ou outros comandos de não-referência, fazendo com que eles falhem.

    
por 04.10.2016 / 17:20