Can I prevent a folder of a certain name being created?
You can't, given the user creating the directory has sufficient permission to write on the parent directory.
You can instead leverage the inotify
family of system calls provided by the Linux kernel, to watch for the creation (and optionally mv
-ing) of directory shop
in the given directory, if created (or optionally mv
-ed), rm
the directory.
The userspace program you need in this case is inotifywait
(comes with inotify-tools
, install it first if needed).
Assuming the directory shop
would be residing in /foo/bar
directory, let's set a monitoring for /foo/bar/shop
creation, and rm
instantly if created:
inotifywait -qme create /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
inotifywait -qme create /foo/bar
watches/foo/bar
directory for any file/directory that might be created i.e. watch for anycreate
eventIf created,
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
checks if the file happens to be a directory and the name isshop
(/,ISDIR shop$/
), if sorm
the directory (system("rm -r -- /foo/bar/shop")
)
You need to run the command as a user that has write permission on directory /foo/bar
for removal of shop
from the directory.
If you want to monitor mv
-ing operations too, add watch for moved_to
event too:
inotifywait -qme create,moved_to /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
Just to note, if you are looking for a file, not directory, named 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") }'
To answer literally based on the question of preventing a folder of a certain name to be created.
touch shop
You can't create a directory if a file with a identical name existing
mkdir: cannot create directory ‘shop’: File exists
What about hijacking mkdir
syscall with 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
Note that inside this handler you can log PID of process that want to create this directory instead:
$ 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
You need to place this in ~/.bashrc
of root (or whoever is running your app) to ensure this will be used:
export LD_PRELOAD=/path/to/test.so