Знайти файли, які користувач не може прочитати?


12

Я хочу знайти файли, які певний користувач не зможе прочитати.

Припустимо, ім’я користувача "user123", і вони знаходяться в групі під назвою "user123". Я хочу знайти файли, які, якщо вони належать користувачу123, мають i + r; якщо цього файлу є груповий користувач123, він повинен мати g + r; якщо це не може, він може мати o + r.

Оскільки GNU find має "читабельний", я можу це зробити:

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

Однак процес повинен запускати користувач, який не має доступу до sudo. Тому я спробував це: (він не перевіряє o + r, але це не важливо на даний момент)

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

але він містить цей файл:

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

Цей файл є єдиним файлом, у /startякому належить user123 з g=rвимкнено. Це ніби знахідка тлумачить -u=rяк -g=r.

Я вирішив спробувати змінити логіку і замість цього випробувати not ( truth ):

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

Це працює!

Чому оригінал findпровалився? Це помилка find(малоймовірна) чи логіка неправильна?

Оновлення: я помилився з логікою. Як було зазначено нижче, оскільки! (A || B || C) == (! A&&! B&&! C) - це два еквівалентні твердження:

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

Моєю метою було не двічі перевіряти користувача / групу. Що мені справді потрібно - це більш складна структура if-then-else, яка, ймовірно, була б можливою лише за наявності оператора -xor. Я міг би створити xor з та / або / ні, але це було б складніше, ніж два рішення, наведені вище.


1
Навіть друга логіка помилкова, тому що вона могла б puppetмати доступ до файлу з --wxrwxrwx puppet puppet.
Стефан Шазелас

Відповіді:


7

Логіка неправильна. Ви думаєте, що цей файл не повинен був бути зазначений у списку, оскільки ним належить user123і rвстановлено біт користувача. Однак він перерахований, оскільки він відповідає другому критерію (він належить групі, user123а група rтрохи не встановлена).

Ваша друга версія працює через один із законів де Моргана : заперечення логічного ORing групи висловлювань логічно еквівалентно AND заперечення окремих тверджень. Іншими словами:

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

Тож робочий findшукає файл, який

  • НЕ (належить користувачеві user123та читається вказаним користувачем) ТА
  • НЕ (належить групі user123та читається вказаною групою) І
  • Не читається у всьому світі.

а перший findшукає файл, який

  • Володіє користувачем user123і не читається цим користувачем АБО
  • Належить групі user123і не читається вказаною групою АБО (якщо ви її заповнили)
  • Не читається у всьому світі

Таким чином, файл, який відповідає БУДЬ-якому з вищезгаданих 3 критеріїв (і не обов'язково всіх), буде вказаний, як ви бачили.

Редагувати

До речі (після перегляду вашого профілю) я є великим шанувальником вашої книги O'Reilly :)


Дякую за аналіз Так, це було неправильним застосуванням закону Моргана. Я намагався це зробити, ( !A && !B && !C )але я перемістив !всередину кожної частини, що не вірно. Спасибі!
TomOnTime

PS Я радий, що ти шанувальник моєї книги! Мені цікаво, на якій мові ви її читали.
TomOnTime,

@TomOnTime Англійська, звичайно. Я намагаюся прочитати будь-яку книгу її мовою оригіналу, якщо можу допомогти.
Джозеф Р.

8

Існує набагато більше речей, які слід врахувати, щоб перевірити, чи має користувач доступ до файлу через заданий шлях:

  • Власник файлу
  • група файлу
  • ACL у файлі
  • uid, gid та додаткові гіди користувача
  • пошук доступу до будь-якого компонента шляху, що веде до цього файлу.
  • чи файл є символьним посиланням
  • дозволи по-різному застосовуються для користувачів id 0.
  • можливо більше функцій безпеки, таких як SELinux ...

Якщо насправді не переключити всі користувальницькі файли та посібники на користувачеві та перевірити, дуже важко реалізувати таку ж логіку, що і система.

З zsh ви можете зробити (як root):

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

Або з perl:

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

Тобто в обох випадках спускайте дерево каталогів як rootтест на доступ до файлів як відповідного користувача.

Працює так, find -readableяк some-userне буде у випадках, коли він не зможе пройти повз каталогів, до яких користувач не має доступу чи не має дозволу на читання (але, можливо, доступ).

Навіть якщо враховувати лише дозвіл і право власності на сам файл (а не ACL або компоненти контуру ...), вам потрібно принаймні (тут синтаксис 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 \)

Ідея полягає в тому, що якщо файл належить користувачеві, всі інші дозволи не мають значення. Якщо ні, то якщо файл належить групі будь-якої з груп користувачів, то дозвіл "інший" не має значення.


1
Хороший момент щодо ACL та інших факторів. Єдина 100% правильна оцінка, access()оскільки вона використовує той самий код ядра, що і open(). Таким чином sudo -u user123 find /start -readable, найкраще рішення, якщо sudoце варіант.
TomOnTime

1
@TomOnTime. Ну ні, якщо ви використовуєте sudo -u user123 find -readable, він не повідомляє про файли в каталогах, в які ви не можете входити, або в каталогах, які ви не можете прочитати (тому будуть помилкові негативи та помилкові позитиви). Ось чому я пропоную використовувати zshдля спуску по дереву каталогів як корінь і зробити access()( [ -r ... ]) в якості фактичного користувача (установка $USERNAMEв zshзмінах всіх UIDS і GID , як sudoби).
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.