Como remover um diretório não vazio que não pertence ao usuário no Linux?

10

Se um diretório "foo" pertencer ao usuário A e contiver um diretório "bar" pertencente à raiz, o usuário A poderá simplesmente removê-lo com rmdir, o que é lógico, porque "foo" é gravável pelo usuário A.

Mas se a "barra" do diretório contiver outro arquivo de propriedade raiz, o diretório não poderá ser removido, porque os arquivos nele deverão ser removidos primeiro e ficar vazios. Mas o "bar" em si não é gravável, portanto, não é possível remover arquivos nele.

Existe uma maneira de contornar isso? Ou me convença de outra forma por que é necessário.

Alex B
fonte

Respostas:

7

Interpretação 1: um diretório é um subespaço do sistema de arquivos. Ele pode ser subdividido em subespaços, criando subdiretórios nele. O proprietário do diretório foodeve ter controle sobre tudo dentro do subespaço: foo/bar, foo/bar/qux, etc.

Interpretação 2: um diretório é um subespaço do sistema de arquivos. Todo diretório é anexado a outro diretório, chamado pai. O proprietário do diretório footem controle sobre tudo dentro do subespaço; no entanto, para um subdiretório foo/bar, o proprietário de footem controle sobre se barpode ser anexado, foomas não sobre o que ocorre dentro bar: apenas o proprietário de bartem controle sobre isso.

Evidências a favor da interpretação 2: como você observou, a maneira como as permissões funcionam. Além disso, o fato de alguns sistemas de arquivos Unix permitirem que um diretório seja anexado a mais de um pai: isso é chamado de ter vários links físicos. (Ter vários links físicos é comum para arquivos regulares, mas geralmente é desencorajado ou proibido para diretórios, principalmente devido ao risco de criação de loops, onde um diretório é o seu próprio avô N vezes removidas - para que você não possa acessá-lo a partir da raiz Também é um problema o que fazer se um diretório tiver 0 links físicos, mas não estiver vazio: como o diretório está desanexado, você deseja excluí-lo, mas o que você faz com o diretório conteúdo?)

Evidências a favor da interpretação 1: na prática, os diretórios têm um único pai e, portanto, formam uma estrutura em árvore. E você não pode acessar, a foo/bar/quxmenos que tenha permissão de execução foo, bem como bar(bem, exceto que existem maneiras um tanto obscuras de obter acesso barsem ter acesso a foo). Portanto, os níveis superiores são importantes.

Em uma nota mais prática, na sua situação, o usuário A pode fazer

mkdir lixo
mv foo / bar lixo /
rmdir foo
Gilles 'SO- parar de ser mau'
fonte
1
Esta é uma ótima resposta (retirada), mas a aparente inconsistência continua sendo frustrante para mim. E embora o exemplo prático de mover barra para lixo funcione, ficamos com um diretório chamado lixo que não pode ser removido. Eu tenho esse mesmo problema, exceto pelo usuário A e pelo usuário B, onde B travou algo em um diretório de propriedade de A, que A deseja remover.
Paul Hooper
Esta é uma boa explicação, mas o exemplo no final mvpara contornar o problema não funciona para mim no Raspbian (não tentei em nenhum outro sistema). Além disso, depois de pesquisar esse problema, não vi o uso mvcomo uma solução mencionada em nenhum outro lugar. De fato, com base no meu entendimento de como as permissões funcionam, faz sentido que as mvfalhas falhem quando eu as tentei. Estou esquecendo de algo? Ou essa funcionalidade talvez tenha mudado? @Gilles @PaulHooper
fvgs
@fvgs Nada mudou, mas sua situação pode ter permissões diferentes para esta. Sugiro que você faça uma nova pergunta (no Unix e Linux, em vez de no Server Fault, pois essa pergunta provavelmente seria considerada fora de tópico se fosse solicitada no SF agora) e forneça todos os detalhes da sua situação.
Gilles 'SO- stop be evil'
@Gilles Você poderia me indicar alguma documentação, referência ou menção do comportamento que você descreveu mv? Eu posso usar mvpara renomear o diretório bar. Significa que o mvêxito é bom, desde que eu não tente mover a barra para fora do diretório atual ou para qualquer outro diretório. Mas o exemplo que você deu (que move a barra acima de um diretório) não funciona para mim (permissão negada). O exemplo que você deu assume condições específicas diferentes daquelas especificadas na pergunta?
Fevgs
@fvgs Meu exemplo não move barum diretório, ele o move para um diretório que você possui. garbagepode estar em qualquer lugar do mesmo sistema de arquivos, não necessariamente um irmão de foo.
Gilles 'SO- stop be evil'
0

A única maneira de contornar isso seria usar um setgid ou setuid no diretório pai ou usar uma ACL.

Defina o diretório setgid com

chmod g+s foo

Defina uma ACL padrão com

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

Isso a define como a ACL padrão nesse caminho. Você deve montar o sistema de arquivos que contém esse caminho com a opção acl!

Agora me diga por que você acha que quer isso.

wzzrd
fonte
Bem, o problema é de consistência. Nada me impede de excluir um arquivo ou um diretório vazio pertencente a outro usuário em um diretório que possuo, mas, se não estiver vazio, estou impedido de excluir meu próprio diretório.
Alex B
Se for esse o caso, eu usaria uma das opções que forneci. Eles vão funcionar bem para você.
Wzzrd
Costumo usar várias contas na minha área de trabalho (uma das quais é a conta "principal não raiz"). Também posso obter essa situação quando make installiniciado a partir do root começa a construir algo.
Vi.
O setgid no diretório pai não ajuda. Depois de feito como root, cd ~user && mkdir qqq && touch qqq/qqqnão consigo me livrar do qqq do usuário por chmod g+s .e rm -Rf qqq.
Vi.
Mmh. Provavelmente é uma questão de umask. Se seu diretório é 775, é setgid e seu umask é 0002, os arquivos são graváveis ​​para o grupo e, portanto, removíveis para você. Mas, é verdade, ele não funciona com umask 0022 (que é principalmente o padrão). Deveria ter dito isso. Você já testou a opção acl?
Wzzrd