¿Puedo evitar que se cree una carpeta con un nombre determinado?

¿Puedo evitar que se cree una carpeta con un nombre determinado?

Estoy trabajando en una aplicación web LAMP y hay un proceso programado en algún lugar que sigue creando una carpeta llamada shopen la raíz del sitio. Cada vez que esto aparece, causa conflictos con las reglas de reescritura en la aplicación, lo cual no es bueno.

Hasta que encuentre el script infractor, ¿hay alguna manera de evitar que shopse cree cualquier carpeta llamada en la raíz? Sé que puedo cambiar los permisos de una carpeta para evitar que se cambie su contenido, pero no he encontrado una manera de evitar que se cree una carpeta con un nombre determinado.

Respuesta1

No puede, dado que el usuario que crea el directorio tiene permiso suficiente para escribir en el directorio principal.

En su lugar, puede aprovechar la inotifyfamilia de llamadas al sistema proporcionadas por el kernel de Linux, para observar la creación (y opcionalmente mv-ing) del directorio shopen el directorio dado, si se crea (u opcionalmente mv-ed), rmel directorio.

El programa de espacio de usuario que necesita en este caso es inotifywait(viene con inotify-tools, instálelo primero si es necesario).


Suponiendo que el directorio shopresidiría en /foo/barel directorio, establezcamos un monitoreo para /foo/bar/shopla creación y, rmal instante, si se crea:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/barvigila /foo/barel directorio para cualquier archivo/directorio que pueda crearse, es decir, vigila cualquier createevento

  • Si se crea, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'verifica si el archivo es un directorio y el nombre es shop( /,ISDIR shop$/), de ser así, rmel directorio ( system("rm -r -- /foo/bar/shop"))

Debe ejecutar el comando como usuario que tiene permiso de escritura en el directorio /foo/barpara eliminarlo shopdel directorio.


Si también desea monitorear mvlas operaciones de -ing, agregue también observar el moved_toevento:

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

Solo para tener en cuenta, si está buscando un archivo, no un directorio, llamado 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") }'

Respuesta2

Para responder literalmente a la pregunta de cómo prevenir unacarpetade un determinado nombre a crear.

touch shop

No puede crear un directorio si existe un archivo con un nombre idéntico

mkdir: cannot create directory ‘shop’: File exists

Respuesta3

¿Qué pasa con el secuestro mkdirde syscall con 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

Tenga en cuenta que dentro de este controlador puede registrar el PID del proceso que desea crear este directorio:

$ 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

Debe colocar esto en ~/.bashrcla raíz (o en quien esté ejecutando su aplicación) para asegurarse de que se use:

export LD_PRELOAD=/path/to/test.so

Respuesta4

Cree un enlace simbólico que apunte a una ubicación inexistente dentro de un directorio inexistente. Esto tiene algunas implicaciones 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 y otros fallarán con EEXIST(El archivo existe).
  2. Intentar abrir la ruta para leer, escribir o agregar fallará con ENOENT(No existe tal archivo o directorio)
  3. El uso de stat(2) (no lstat(2) o stat(1)) en la ubicación también falla con ENOENT. Por supuesto, lstat devolverá la información sobre el enlace simbólico.

Esto tiene dos ventajas sobre algunas de las otras soluciones propuestas aquí: (a) no necesita ejecutar un servicio que rastree la creación del directorio y (b) el nombre parece no existir para la mayoría de los comandos.

Tendrás que intentarlo, pero sospecho que cualesquiera que sean las reglas de reescritura que tengas, no usan lstat u otros comandos sin desreferencia, lo que las hace fallar.

información relacionada