Как удалить непустой каталог, который не принадлежит пользователю в Linux?

10

Если каталог «foo» принадлежит пользователю A и содержит каталог «bar», которым владеет root, пользователь A может просто удалить его rmdir, что логично, поскольку «foo» доступен для записи пользователю A.

Но если в каталоге «bar» содержится другой файл, принадлежащий корню, каталог нельзя удалить, так как сначала необходимо удалить файлы в нем, чтобы он стал пустым. Но сама «панель» недоступна для записи, поэтому в ней невозможно удалить файлы.

Есть ли способ обойти это? Или, убедите меня иначе, зачем это нужно.

Алекс Б
источник

Ответы:

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). Так что верхние уровни имеют значение.

С практической точки зрения, в вашей ситуации, пользователь А может сделать

макдир мусор
мв фу / бар мусор /
рмдир фу
Жиль "ТАК - перестань быть злым"
источник
1
Это отличный ответ (reced), но кажущаяся несогласованность по-прежнему разочаровывает меня. И хотя практический пример перемещения бара в мусор работает, у нас остался каталог мусора, который нельзя удалить. У меня та же проблема, за исключением того, что это пользователь A и пользователь B, где B вставил что-то в каталог, принадлежащий A, который A хочет удалить.
Пол Хупер
Это хорошее объяснение, но пример в конце использования, mvчтобы обойти проблему, не работает для меня на Raspbian (не пробовал ни на каких других системах). Кроме того, изучив эту проблему, я не видел использования mvв качестве решения, упомянутого где-либо еще. На самом деле, исходя из моего понимания того, как работают разрешения, становится понятным, что происходит mvсбой, когда я пытался это сделать. Я что-то упускаю? Или эта функциональность, возможно, изменилась? @Gilles @PaulHooper
fvgs
@fvgs Ничего не изменилось, но у вашей ситуации могут быть другие разрешения. Я предлагаю вам задать новый вопрос (о Unix и Linux, а не о сбое сервера, поскольку этот вопрос, вероятно, будет считаться не относящимся к теме, если бы его сейчас задавали на SF), и сообщить все подробности вашей ситуации.
Жиль "ТАК - перестань быть злым"
@ Жиль Не могли бы вы указать мне некоторую документацию, ссылку или упоминание о поведении, которое вы описали mv? Я могу использовать mvдля переименования директории бара. Это означает, что это mvудается, пока я не пытаюсь переместить панель за пределы текущего каталога или в любой другой каталог. Но приведенный вами пример (который перемещает панель вверх по каталогу) не работает для меня (разрешение отклонено). Предполагается ли в приведенном вами примере конкретные условия, отличные от указанных в вопросе?
августа
@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
источник
Ну, проблема заключается в последовательности. Ничто не мешает мне удалить файл или пустой каталог, принадлежащий другому пользователю, в каталоге, которым я владею, но если он не пустой, я не могу удалить свой собственный каталог.
Алекс Б
Если это так, я бы использовал один из предложенных вариантов. Они будут хорошо работать для вас.
wzzrd
Я часто использую несколько учетных записей на своем рабочем столе (одна из которых является основной учетной записью без полномочий root). Я также могу получить такую ​​ситуацию, когда при make installзапуске от root начинает что-то строить.
Ви.
setgid в родительском каталоге не помогает. После того, как все сделано как root, cd ~user && mkdir qqq && touch qqq/qqqя не могу избавиться от qqq от пользователя chmod g+s .и rm -Rf qqq.
Ви.
Ммм. Это, вероятно, вопрос umask тогда. Если ваш каталог 775, он setgid и ваш umask 0002, тогда файлы доступны для записи для группы и, следовательно, для вас. Но, правда, он не работает с umask 0022 (который в основном используется по умолчанию). Должен был сказать это. Вы тестировали опцию acl?
wzzrd