Як видалити не порожній каталог, який не належить користувачеві в Linux?


10

Якщо каталог "foo" належить користувачеві A і містить каталог "bar", який належить root, користувач A може просто видалити його rmdir, що логічно, оскільки "foo" може бути записаний користувачем A.

Але якщо каталог "bar" містить інший файл, що належить root, каталог не може бути видалений, оскільки файли в ньому потрібно видалити спочатку, тому він стає порожнім. Але сам "бар" не піддається запису, тому видалити файли в ньому неможливо.

Чи є шлях до цього? Або переконайте мене в іншому, чому це потрібно.

Відповіді:


7

Тлумачення 1: каталог - це підпростір файлової системи. Його можна додатково підрозділити на підпростори, створивши в ньому підкаталоги. Власник директорії fooповинен мати контроль над усім всередині підпростору: foo/bar, foo/bar/quxі т.д.

Тлумачення 2: каталог - це підпростір файлової системи. Кожен каталог додається до якогось іншого каталогу, який називається його батьківським. Власник каталогу fooмає контроль над усім, що знаходиться всередині підпростору; однак для підкаталогу foo/barвласник fooмає контроль над тим, чи barможе бути приєднаний, fooале не над тим, що знаходиться всередині bar: лише власник barмає контроль над цим.

Докази на користь тлумачення 2: як ви зазначили, спосіб роботи дозволів. Також той факт, що деякі файлові системи Unix дозволяють приєднувати каталог до більш ніж одного з батьків: це називається тим, що має декілька жорстких посилань. (Наявність декількох жорстких посилань є звичайними для звичайних файлів, але це зазвичай не рекомендується або заборонено для каталогів, головним чином через ризик створення циклів, де каталог видаляється власним бабусею та дідусем N разів, тому ви не можете дістатись до нього з кореня каталог, який є дуже поширеним очікуванням. Існує також проблема, що робити, якщо в каталозі 0 жорстких посилань, але він не порожній: оскільки каталог не приєднаний, ви хочете його видалити, але що робити з його вміст?)

Докази на користь інтерпретації 1: на практиці каталоги мають єдиного батьківського складу і тому утворюють структуру дерева. І ви не може отримати доступ , foo/bar/quxякщо у вас немає прав на виконання foo, а також bar(ну, за винятком того, що є декілька нерозв'язаних способів бути надано доступ до barбез надання доступу до foo). Отже, верхні рівні мають значення.

Що стосується більш практичної уваги, у вашій ситуації користувач A може це зробити

mkdir сміття
mv foo / бар сміття /
rmdir foo

1
Це чудова відповідь (сказано), але явна непослідовність залишається мені неприємною. І хоча практичний приклад переміщення бару до сміття працює, ми залишаємося з каталогом сміття, яке неможливо видалити. У мене є ця сама проблема, за винятком того, що це користувач A і користувач B, де B вклав щось у каталог, що належить A, який A хоче видалити.
Пол Хупер

Це хороше пояснення, але приклад в кінці, який використовується mvдля обходу проблеми, не працює для мене на Raspbian (не пробував на будь-яких інших системах). Крім того, досліджуючи це питання, я не бачив використання цього mvрішення як ніде. Дійсно, виходячи з мого розуміння того, як працюють дозволи, має сенс, що mvне вдалося, коли я спробував це. Я щось пропускаю? Або, можливо, ця функціональність змінилася? @Gilles @PaulHooper
fvgs

@fvgs Нічого не змінилося, але у вашої ситуації можуть бути різні дозволи від цього. Я пропоную вам задати нове запитання (про Unix & Linux, а не про помилку сервера, оскільки це питання, мабуть, вважатиметься поза темою, якби його задали в SF зараз) і дайте всі деталі вашої ситуації.
Жил "ТАК - перестань бути злим"

@Gilles Чи не могли б ви вказати мені якусь документацію, посилання чи згадку про поведінку, яку ви описали mv? Я можу використовувати mvдля перейменування штрихової директорії. Це означає, що це mvдосягає успіху, якщо я не намагаюся перемістити панель за межі поточного каталогу або в будь-який інший каталог. Але приклад, який ви подали (який переміщує смужку вгору до каталогу), для мене не працює (у дозволі відмовлено). Чи приклад, який ви навели, передбачає конкретні умови, відмінні від зазначених у запитанні?
fvgs

@fvgs Мій приклад не переміщує barвгору каталог, він переміщує його до каталогу, який є у вас. garbageможе знаходитися в будь-якому місці однієї файлової системи, не обов'язково побратимів foo.
Жил "ТАК - перестань бути злим"

0

Єдиним способом цього було б використовувати або setgid або setuid у батьківському каталозі, або використовувати ACL.

Встановіть каталог setgid за допомогою

chmod g+s foo

Встановіть для нього ACL за замовчуванням за допомогою

setfacl -d -R -m g:group:rwx foo

Це встановлює його як ACL за замовчуванням на цьому шляху. Ви маєте змонтувати файлову систему, що містить цей шлях, за допомогою параметра acl!

Тепер скажи мені, чому ти думаєш, що цього хочеш.


Ну, проблема полягає в послідовності. Ніщо не заважає мені видалити файл або порожній каталог, який належить іншому користувачу, у власному каталозі, але якщо він не порожній, я не можу видалити власний каталог.
Алекс Б

Якщо це так, я б використав один із запропонованих мною варіантів. Вони будуть добре працювати для вас.
wzzrd

Я часто використовую кілька облікових записів на своєму робочому столі (один з них - "основний некоріозний" рахунок). Я також можу отримати таку ситуацію, коли make installпочаток з root починає щось будувати.
Ві.

setgid у батьківському каталозі не допомагає. Після завершення як root cd ~user && mkdir qqq && touch qqq/qqqя не можу позбутися qqq від користувача користувачем chmod g+s .та rm -Rf qqq.
Ві.

Ммм. Це, мабуть, справа умаску. Якщо у вашому каталозі 775, це setgid, а ваш umask - 0002, то файли можна записати для групи та, отже, можна знімати для вас. Але, правда, це не працює з umask 0022 (що є головним чином за замовчуванням). Треба було це сказати. Ви протестували варіант acl?
wzzrd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.