Belirli bir adda bir klasörün oluşturulmasını engelleyebilir miyim?


16

Ben bir LAMP web uygulaması üzerinde çalışıyorum ve bir yerde shopsitenin kök denilen bir klasör oluşturmaya devam eden zamanlanmış bir süreç var . Bu her göründüğünde, uygulamada yeniden yazma kurallarıyla çakışmaya neden olur, iyi değil.

Sorun shopyaratan komut dosyasını bulana kadar , kökte oluşturulan herhangi bir klasörün önlenmesinin bir yolu var mı? İçeriğinin değiştirilmesini önlemek için bir klasördeki izinleri değiştirebileceğimi biliyorum, ancak belirli bir adda bir klasörün oluşturulmasını önlemenin bir yolunu bulamadım.


4
Oluşturma işleminin ne yaptığını öğrenmek için denetimi etkinleştirebilirsiniz .
Andrew Henle

Yanıtlar:


30

Dizini oluşturan kullanıcının üst dizine yazmak için yeterli izni varsa, yapamazsınız.

Bunun yerine , dizinin oluşturulduğu (veya isteğe bağlı olarak -edildiği) dizinde dizinin inotifyoluşturulmasını (ve isteğe bağlı olarak mv-ing) izlemek için Linux çekirdeği tarafından sağlanan sistem çağrıları ailesinden yararlanabilirsiniz .shopmvrm

Bu durumda ihtiyacınız olan kullanıcı alanı programı inotifywait(ile birlikte gelir inotify-tools, gerekirse önce kurun).


Dizin varsayarsak shopikamet olacağını /foo/bardizine, en bir izleme ayarlayalım /foo/bar/shopoluşturulması ve rmoluşturulan eğer anında:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/barsaatler /foo/barherhangi yani izlemek yaratılabilecek her dosya / dizin için dizin createolay

  • Oluşturulmuşsa, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'dosyanın bir dizin olup olmadığını ve adının shop( /,ISDIR shop$/) olduğunu kontrol eder, öyleyse rmdizin ( system("rm -r -- /foo/bar/shop"))

Komutu /foo/bardizinden kaldırmak için dizinde yazma iznine sahip bir kullanıcı olarak çalıştırmanız gerekir shop.


mv-İng işlemlerini de izlemek istiyorsanız , moved_toetkinlik için de saat ekleyin :

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

Sadece şunu belirtmek gerekir shop: Dizin değil, bir dosya arıyorsanız :

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") }'

2
Dahası, bunu inotifywaityapmak için kullanıyorsanız , tetikleyicinin de süreci yakalayabilmesi mümkündürps -ef
roaima

30

Belirli bir adda bir klasörün oluşturulmasını önleme sorusuna dayalı olarak cevaplamak .

touch shop

Aynı ada sahip bir dosya varsa dizin oluşturamazsınız

mkdir: cannot create directory ‘shop’: File exists


6
Bu * yeterli olmayabilir. mkdir bunu yapamayabilir, fakat yapılabilir. Yine de iyi bir ilk deneyin.
coteyr

9
Linux sistemlerinde chattr +i shopdeğişmez hale getirmek için kullanın . Değişmez bayrak kaldırılıncaya kadar yeniden adlandırılamaz / silinemez.
R .. GitHub BUZA YARDIMCI DURDUR

1
Bu akıllı bir hile, durumum için pek doğru değil ama belirli durumlar için akıllı bir fikir 👍
Andrew

1
@R .. ilginç. rename(2)Hala çalışmam bekleniyordu , çünkü isim inode'nun bir parçası değil, ama çalışmıyor. Hızlı internet araması nedenini göstermez. İpucu var mı?
domen

@domen: Çünkü bu "değişmez" özelliğin amacının bir parçası. Çalışmayı önlemek için uygulama düzeyinde önemsiz ekstra işler gerektirdiğinden şüpheleniyorum rename.
R .. GitHub BUZA YARDIMCI DURDUR

4

Sistem mkdirçağrılarını ele geçirmeye ne dersiniz 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

Bu işleyicinin içinde, bunun yerine bu dizini oluşturmak isteyen işlemin PID'sini günlüğe kaydedebileceğinizi unutmayın:

$ 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

Bunun ~/.bashrckullanıldığından emin olmak için bunu kök dizinine (veya uygulamanızı kim çalıştırıyorsa) yerleştirmeniz gerekir:

export LD_PRELOAD=/path/to/test.so

2
Bu bir düşüş olmamalı, bu bir çözüm ve iyi bir
kedi

4
Bir teneke fasulye açmak için bir bavul nuke kullanıyor. Ama hey en azından pişirilecekler ...
Monica ile Hafiflik Yarışları

2
@cat: Katılmıyorum. LD_PRELOADbunun gibi kesmek temelde her zaman yanlıştır ve ne yaptığınızı bilmiyorsanız, değiştirdiğiniz işlevin asenkron sinyal güvenliği gibi özellikleri bozarak yüklediğiniz programı kötü bir şekilde kırabilirler.
R .. GitHub BUZA YARDIMCI DURDUR

1
Ayrıca, bence fopenolması gereken "a"yerine "w"önceki günlükleri koruyabilir, böylece
kedi

2
Bozuk kod sistem aramasını libc yoluyla değil, doğrudan çağırırsa da bu çalışmaz. Veya hatalı kod statik olarak bağlıysa.
domen

3

(Miati'nin cevabı hakkında yorum yapardı, ancak eski hesabımı hatırlayamıyorum ve bu yeni hesapta yeterli itibara sahip değilim ...)

Bir dosya oluşturarak ve ardından dosya özniteliklerini değiştirerek oluşturma işlemini engelleyebilirsiniz.

$ sudo touch shop
$ sudo chattr +i shop

Ardından, kullanıcı kök olsa bile, bu dosyayla herhangi bir şey yapma girişimi engellenir.

$ 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

2
Eski hesabınızın adını / e-posta adresini biliyorsanız, her sayfanın altında bulunan iletişim formundan bir hesap birleştirmesi isteyebilirsiniz .
wizzwizz4

Ayrıca, neden göndermeye karar verdiğinizden ziyade, bunun diğer cevapla nasıl ilişkili olduğunu anlatmıyorsunuz?
jpaugh

2

Varolmayan bir dizinde varolmayan bir konuma işaret eden bir simge bağlantısı oluşturun. Bunun bazı eğlenceli sonuçları var:

$ 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 ve diğerleri EEXIST(Dosya var) ile başarısız olur .
  2. Okuma, yazma veya ekleme yolunu açma girişimi başarısız olur ENOENT(Böyle bir dosya veya dizin yok)
  3. Konumda stat (2) (lstat (2) veya stat (1) değil) kullanılması da başarısız olur ENOENT. lstat elbette symlink hakkındaki bilgileri döndürecektir.

Bu, burada önerilen diğer çözümlerden bazılarına göre iki avantaja sahiptir: (a) dizinin oluşturulmasını izleyen bir hizmete ihtiyacınız yoktur ve (b) adın çoğu komut için var olmadığı anlaşılmaktadır.

Bunu denemek zorunda kalacaksınız, ancak yeniden yazma kurallarınız ne olursa olsun, lstat veya diğer kayıt dışı bırakma komutlarını kullanmadıklarından şüpheleniyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.