Bir kullanıcının okuyamayacağı dosyalar mı buldunuz?


12

Belirli bir kullanıcının okuyamayacağı dosyaları bulmak istiyorum.

Kullanıcı adının "user123" olduğunu ve "user123" adlı bir grupta olduklarını varsayın. Ben kullanıcı123 sahip oldukları u + r sahip dosyaları bulmak istiyorum; dosya kullanıcı123 grubu ise, g + r açık olmalıdır; başarısız olursa o + r açık olabilir.

GNU bulgusu "okunabilir" olduğundan, bunu yapabilirim:

sudo -u user123 find /start ! -readable -ls

Ancak bu işlem sudo erişimi olmayan bir kullanıcı tarafından çalıştırılmalıdır. Bu nedenle II bunu denedi: (o + r'yi kontrol etmiyor, ancak bu noktada önemli değil)

find /start \( -user user123 ! -perm -u=r  \) -o \( -group user123 ! -perm -g=r  \) -ls

ancak bu dosyayı listeler:

272118    4 -rw-------   1 user123   user123       3243 Jul  3 19:50 /start/blah/blah/file.txt

Bu dosya, /startuser123 tarafından g=rkapalı olan tek dosyadır . Bulmak yorumluyor sanki -u=rkadar -g=r.

Mantığı tersine çevirmeye karar verdim ve bunun yerine test ettim not ( truth ):

find /etc/puppet ! \( \( -user puppet -perm -u=r  \) -o \( -group puppet -perm -g=r \) -o \( -perm -o=r \) \)  -ls

Bu çalışır!

Orijinal neden findbaşarısız oldu? Bu bir hata mı find(olası değil) veya mantık yanlış mı?

Güncelleme: Mantık yanlıştı. Aşağıda belirtildiği gibi, o zamandan beri! (A || B || C) == (! A &&! B &&! C) bunlar iki eşdeğer ifadedir:

find /start ! \( \( -user user123 -perm -u=r \) -o \( -group user123 -perm -g=r \) -o \( ! \( -user user123 -o -group user123 \) -perm -o=r \) \) -ls
find /start ! \( -user user123 -perm -u=r \) ! \( -group user123 -perm -g=r \) ! \( ! \( -user user123 -o -group user123 \) -perm -o=r \) -ls

Amacım kullanıcı / grubu iki kez test etmek zorunda değildi. Gerçekten ihtiyacım olan daha karmaşık bir if-then-else yapısı, muhtemelen sadece -xor operatörü olsaydı mümkün olurdu. Bir xor oluşturabilirim ve / veya / değil ama yukarıdaki iki çözümden daha karmaşık olurdu.


1
İkinci mantık bile yanlıştır, çünkü puppetile bir dosyaya erişimi vardır --wxrwxrwx puppet puppet.
Stéphane Chazelas

Yanıtlar:


7

Mantık yanlış. Sahip olduğunuz user123ve kullanıcının rbit ayarlı olduğu için bu dosyanın listelenmemiş olması gerektiğini düşünüyorsunuz . (O grup tarafından sahibi olduğu ikinci kritere uyum Ancak, Listelenmişse user123ve grubun sahip rbit unset) '.

İkinci sürümünüz de Morgan yasalarından biri nedeniyle çalışır : bir ifade grubunun mantıksal ORing değerinin reddedilmesi mantıksal olarak tek tek deyimlerin reddine VE eşdeğerdir. Başka bir deyişle:

 ! ( A || B || C ) == ( !A && !B && !C )

Bu yüzden çalışma find,

  • (Kullanıcıya ait user123ve adı geçen kullanıcı tarafından okunabilir) VE
  • (Gruba ait user123ve söz konusu gruba göre okunabilir) VE
  • Dünya tarafından okunamaz.

ilki findbir dosyayı ararken

  • Kullanıcıya aittir user123ve söz konusu kullanıcı tarafından okunamaz VEYA
  • Gruba aittir user123ve adı geçen grup tarafından okunamaz VEYA (eğer tamamladıysanız)
  • Dünya tarafından okunamıyor

Bu nedenle, yukarıdaki 3 ölçütten HERHANGİ BİRİ ile eşleşen (ve mutlaka hepsi değil) bir dosya gördüğünüz gibi listelenir.

Düzenle

Bu arada (profilinizi görüntüledikten sonra), O'Reilly kitabınızın büyük bir hayranıyım :)


Analiz için teşekkürler. Evet, Morgan yasasının bir yanlış uygulamasıydı. Yapmaya çalışıyordum ( !A && !B && !C )ama !her parçanın iç kısmına taşındım , ki bu geçerli değil. Teşekkürler!
TomOnTime

PS: Kitabımın hayranı olmana sevindim! Hangi dilde okuduğunuzu merak ediyorum.
TomOnTime

@TomOnTime İngilizce, elbette. Eğer yardımcı olabilirsem herhangi bir kitabı orijinal dilinde okumaya çalışırım.
Joseph

8

Bir kullanıcının belirli bir yoldan bir dosyaya erişip erişmediğini kontrol etmek için dikkate alınması gereken çok daha fazla şey vardır:

  • Dosyanın sahibi
  • dosya grubu
  • dosyadaki ACL'ler
  • kullanıcının uid, gid ve ek kılavuzları
  • o dosyaya giden herhangi bir yol bileşenine erişim arayın.
  • dosyanın bir sembol bağlantısı olup olmadığı
  • 0 kimliğine sahip kullanıcılar için farklı izinler geçerlidir.
  • SELinux gibi daha fazla güvenlik özelliği ...

Aslında tüm uids ve gids kullanıcı olanlara geçmek ve kontrol etmek, sistemin yaptığı ile aynı mantığı uygulamak çok zordur.

Zsh ile şunları yapabilirsiniz (root olarak):

readable() (
  USERNAME=$u
  [ -r "$REPLY" ]
)
u=some-user
print -rl -- **/*(DoN^+readable)

Veya perl:

find . -print0 | sudo -u some-user perl -Mfiletest=access -l -0ne '
  print unless -r'

Her iki durumda da, dizin ağacını aşağıdaki gibi inin, rootancak ilgili kullanıcı olarak dosya erişimini test edin.

Koşu find -readableolarak some-userdurumlarda olmayacak kullanıcının erişimi veya hiç okuma izni (ama muhtemelen erişime) sahip olduğu dizinlere geçmiş gitmek mümkün olmayacaktır olarak.

Yalnızca dosyanın kendisinin iznini ve sahipliğini göz önünde bulundururken (ACL'ler veya yol bileşenleri değil ...) en azından (burada GNU sözdizimi) gerekir:

u=some-user; g=$(id -G "$u" | sed 's/ / -o -group /g'); IFS=" "
find . ! \( -user "$u" -perm -u=r -o \
          ! -user "$u" \( -group $g \) -perm -g=r -o \
          ! -user "$u" ! \( -group $g \) -perm -o=r \)

Buradaki fikir, dosya kullanıcıya aitse, diğer tüm izinlerin alakasız olmasıdır. Değilse, dosya kullanıcı gruplarından herhangi birinin grubuna aitse, "diğer" izni ilgisizdir.


1
ACL'ler ve diğer faktörler hakkında iyi bir nokta. Tek% 100 doğru değerlendirme, access()aynı çekirdek kodunu kullanmasıdır open(). Bu bir seçenek sudo -u user123 find /start -readableise en iyi çözümdür sudo.
TomOnTime

1
@TomOnTime. Hayır, kullanırsanız sudo -u user123 find -readable, giremeyeceğiniz dizinlerde veya okuyamayacağınız dizinlerdeki dosyaları bildirmez (bu nedenle yanlış negatifler ve yanlış pozitifler olacaktır). Ben kullanmanızı öneririz yüzden en zshroot olarak dizin ağacını inen ve do access()( [ -r ... ]fiili kullanıcı olarak) (ayar $USERNAMEiçinde zshdeğişikliklere bütün kullanıcı kimlikleri ve gid'leri gibi sudoolur).
Stéphane Chazelas
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.