回答:
ディレクトリを作成しているユーザーに、親ディレクトリに書き込むための十分なアクセス許可がある場合は、できません。
代わりに活用することができますinotify
作成を監視するために、Linuxのカーネルが提供するシステムコールの家族を(必要に応じてmv
-ing)ディレクトリのshop
作成(または必要に応じている場合、指定されたディレクトリにmv
-ed)、rm
ディレクトリ。
この場合に必要なユーザー空間プログラムは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") }'
inotifywait
これを行うために使用している場合、トリガーがプロセスをキャッチできる可能性もありますps -ef
特定の名前のフォルダーが作成されないようにするという質問に基づいて、文字通り答えます。
touch shop
同じ名前のファイルが存在する場合、ディレクトリを作成できません
mkdir: cannot create directory ‘shop’: File exists
chattr +i shop
不変にするために使用します。不変フラグが削除されるまで、名前の変更や削除はできません。
rename(2)
名前はiノードの一部ではありませんが、機能しないため、引き続き機能することを期待していました。簡単なインターネット検索では、その理由が明らかになりません。ヒントはありますか?
rename
動作を防ぐためには、実装レベルで重要な追加作業が必要だと思います。
...でmkdir
syscallをハイジャックするのはどう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
LD_PRELOAD
このようなハックは基本的に常に間違っており、何をしているのかわからない限り、置き換える関数のasync-signal-safetyのようなプロパティを壊すことで、ロードするプログラムをひどく壊す可能性があります。
fopen
必要があります"a"
代わりに"w"
、それは以前のログ保存することができますので、
(Miatiの答えについてコメントしたはずですが、私の古いアカウントを思い出せず、この新しいアカウントについて十分な評判がありません...)
ファイルを作成してからファイル属性を変更することにより、作成をブロックできます。
$ sudo touch shop
$ sudo chattr +i shop
その後、そのファイルで何かをしようとすると、ユーザーが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
存在しないディレクトリ内の存在しない場所を指すシンボリックリンクを作成します。これにはいくつかの楽しい意味があります。
$ 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
EEXIST
(File exists)で失敗します。ENOENT
(そのようなファイルまたはディレクトリはありません)ENOENT
ます。lstatはもちろん、シンボリックリンクに関する情報を返します。これには、ここで提案する他のソリューションよりも2つの利点があります。(a)ディレクトリの作成を追跡するサービスを実行する必要はありません。(b)ほとんどのコマンドには名前が存在しないようです。
試してみる必要がありますが、書き換えルールが何であれ、lstatや他の非参照コマンドを使用しないため、失敗します。