Temukan file yang tidak dapat dibaca pengguna?

12

Saya ingin mencari file yang tidak dapat dibaca pengguna tertentu.

Asumsikan nama pengguna adalah "user123" dan mereka berada dalam grup yang disebut "user123". Saya ingin mencari file itu, jika mereka dimiliki oleh user123 memiliki u + r aktif; gagal bahwa jika file tersebut adalah grup user123 itu seharusnya memiliki g + r aktif; gagal karena dapat mengaktifkannya.

Karena GNU find memiliki "-baca", saya bisa melakukan ini:

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

Namun proses tersebut harus dijalankan oleh pengguna yang tidak memiliki akses sudo. Oleh karena itu saya mencoba ini: (tidak memeriksa o tapi r tapi itu tidak penting pada saat ini)

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

tetapi daftar file ini:

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

File ini adalah satu-satunya file di bawah /startyang dimiliki oleh user123 dengan tidak g=raktif. Seolah menemukan menafsirkan -u=rsebagai -g=r.

Saya memutuskan untuk mencoba membalikkan logika dan sebagai gantinya menguji not ( truth ):

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

Itu bekerja!

Mengapa yang asli findgagal? Apakah itu bug di find(tidak mungkin) atau apakah logikanya salah?

Pembaruan: Logika saya salah. Seperti yang ditunjukkan di bawah, sejak! (A || B || C) == (! A &&! B &&! C) ini adalah dua pernyataan yang ekuivalen:

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

Tujuan saya adalah tidak harus menguji pengguna / grup dua kali. Yang benar-benar saya butuhkan adalah struktur if-then-else yang lebih rumit, yang mungkin hanya mungkin terjadi jika ada operator -xor. Saya dapat membangun xor dari dan / atau / tidak tetapi itu akan lebih kompleks daripada dua solusi di atas.

TomOnTime
sumber
1
Bahkan logika kedua salah, karena akan mengatakan puppetmemiliki akses ke file dengan --wxrwxrwx puppet puppet.
Stéphane Chazelas

Jawaban:

7

Logikanya salah. Anda berpikir file ini seharusnya tidak terdaftar karena dimiliki oleh user123dan memiliki rbit set pengguna. Namun, ini terdaftar karena cocok dengan kriteria kedua (dimiliki oleh grup user123dan rsedikit tidak disetel).

Versi kedua Anda berfungsi karena salah satu hukum de Morgan : meniadakan logika ORing dari sekelompok pernyataan secara logika setara dengan ANDing negasi dari masing-masing pernyataan. Dengan kata lain:

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

Jadi pengerjaannya findsedang mencari file itu

  • Tidak (dimiliki oleh pengguna user123dan dapat dibaca oleh pengguna tersebut) DAN
  • Tidak (dimiliki oleh grup user123dan dapat dibaca oleh grup tersebut) DAN
  • Tidak bisa dibaca dunia.

sedangkan yang pertama findmencari file itu

  • Dimiliki oleh pengguna user123dan tidak dapat dibaca oleh pengguna tersebut ATAU
  • Dimiliki oleh grup user123dan tidak dapat dibaca oleh grup tersebut ATAU (jika Anda telah menyelesaikannya)
  • Tidak bisa dibaca dunia

Jadi file yang cocok dengan salah satu dari 3 kriteria di atas (dan belum tentu semua) akan terdaftar seperti yang Anda lihat.

Edit

Kebetulan (setelah melihat profil Anda), saya penggemar buku O'Reilly Anda :)

Joseph R.
sumber
Terima kasih untuk analisisnya. Ya, itu salah penerapan hukum Morgan. Saya coba lakukan ( !A && !B && !C )tetapi saya pindah !ke bagian dalam setiap bagian, yang tidak valid. Terima kasih!
TomOnTime
PS Saya senang Anda penggemar buku saya! Saya ingin tahu bahasa apa yang Anda baca.
TomOnTime
@TomOnTime Bahasa Inggris, tentu saja. Saya mencoba membaca buku apa pun dalam bahasa aslinya jika saya bisa membantu.
Joseph R.
8

Ada banyak hal lain yang perlu dipertimbangkan untuk memeriksa apakah pengguna memiliki akses ke file melalui jalur yang diberikan:

  • Pemilik file
  • grup file
  • ACL dalam file
  • gid, gid, dan gid tambahan pengguna
  • cari akses ke komponen jalur yang mengarah ke file itu.
  • apakah file tersebut merupakan symlink
  • izin berlaku berbeda untuk pengguna id 0.
  • mungkin lebih banyak fitur keamanan seperti SELinux ...

Singkat dari benar-benar beralih semua uids dan gids ke pengguna dan periksa, sangat sulit untuk menerapkan logika yang sama dengan apa yang dilakukan sistem.

Dengan zsh, Anda dapat melakukan (sebagai root):

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

Atau dengan perl:

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

Itu dalam kedua kasus, turun pohon direktori sebagai roottetapi uji untuk akses file sebagai pengguna yang sesuai.

Berjalan find -readableseperti some-usertidak dalam kasus karena tidak akan dapat melewati direktori yang pengguna tidak memiliki akses atau tidak memiliki izin baca (tetapi mungkin mengakses).

Bahkan ketika hanya mempertimbangkan izin dan kepemilikan file itu sendiri (dan bukan ACL atau komponen path ...), Anda memerlukan setidaknya (di sini sintaksis GNU):

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 \)

Gagasannya adalah bahwa jika file tersebut dimiliki oleh pengguna, semua izin lainnya tidak relevan. Jika tidak, maka jika file tersebut milik grup oleh salah satu grup pengguna, maka izin "lain" tidak relevan.

Stéphane Chazelas
sumber
1
Poin bagus tentang ACL dan faktor lainnya. Satu-satunya penilaian yang benar 100% adalah access()karena menggunakan kode kernel yang sama dengan open(). Dengan demikian sudo -u user123 find /start -readableadalah solusi terbaik jika sudomerupakan opsi.
TomOnTime
1
@ TomOnTime. Yah tidak, jika Anda menggunakan sudo -u user123 find -readable, itu tidak akan melaporkan file dalam direktori yang tidak dapat Anda masukkan, atau dalam direktori Anda tidak dapat membaca (jadi akan ada negatif palsu dan positif palsu). Itu sebabnya saya sarankan menggunakan zshuntuk turun pohon direktori sebagai root dan do access()( [ -r ... ]) sebagai pengguna yang sebenarnya (pengaturan $USERNAMEdalam zshmengubah semua uids dan gids seperti sudomau).
Stéphane Chazelas