¿Cómo eliminar un directorio no vacío que no es propiedad del usuario en Linux?

10

Si un directorio "foo" es propiedad del usuario A y contiene una "barra" de directorio, que es propiedad de root, el usuario A simplemente puede eliminarlo con rmdir, lo cual es lógico, porque "foo" es editable por el usuario A.

Pero si la "barra" del directorio contiene otro archivo propiedad de la raíz, el directorio no se puede eliminar, ya que los archivos deben eliminarse primero, por lo que queda vacío. Pero la "barra" en sí no se puede escribir, por lo que no es posible eliminar archivos en ella.

¿Hay alguna forma de evitarlo? O, convencerme de lo contrario por qué es necesario.

Alex B
fuente

Respuestas:

7

Interpretación 1: un directorio es un subespacio del sistema de archivos. Se puede subdividir aún más en subespacios creando subdirectorios en él. El propietario del directorio foodebe tener control sobre todo dentro del subespacio: foo/bar, foo/bar/qux, etc.

Interpretación 2: un directorio es un subespacio del sistema de archivos. Cada directorio está conectado a otro directorio, llamado padre. El propietario del directorio footiene control sobre todo dentro del subespacio; sin embargo, para un subdirectorio foo/bar, el propietario de footiene control sobre si barse puede adjuntar foopero no sobre lo que hay dentro bar: solo el propietario de bartiene control sobre eso.

Evidencia a favor de la interpretación 2: como ha notado, la forma en que funcionan los permisos. Además, el hecho de que algunos sistemas de archivos Unix permiten adjuntar un directorio a más de un padre: esto se llama tener múltiples enlaces duros. (Tener múltiples enlaces duros es común para los archivos normales, pero generalmente se desaconseja o prohíbe para los directorios principalmente debido al riesgo de crear bucles, donde un directorio es su propio abuelo N veces eliminado, por lo que no puede acceder a él desde la raíz directorio, que es una expectativa muy común. También existe el problema de qué hacer si un directorio tiene 0 enlaces duros pero no está vacío: dado que el directorio no está conectado, querrás eliminarlo, pero ¿qué haces con su directorio? ¿contenido?)

Evidencia a favor de la interpretación 1: en la práctica, los directorios tienen un solo padre y, por lo tanto, forman una estructura de árbol. Y no puede acceder a foo/bar/quxmenos que tenga permiso de ejecución fooy también bar(bueno, excepto que hay formas algo oscuras de tener acceso barsin tener acceso a foo). Entonces los niveles superiores sí importan.

En una nota más práctica, en su situación, el usuario A puede hacer

basura mkdir
mv foo / bar basura /
rmdir foo
Gilles 'SO- deja de ser malvado'
fuente
1
Esta es una gran respuesta (recitada), pero la aparente inconsistencia sigue siendo frustrante para mí. Y aunque el ejemplo práctico de mover la barra a la basura sí funciona, nos queda un directorio llamado basura que no se puede eliminar. Tengo este mismo problema, excepto que es el usuario A y el usuario B, donde B pegó algo en un directorio propiedad de A, que A quiere eliminar.
Paul Hooper
Esta es una buena explicación, pero el ejemplo al final mvpara evitar el problema no me funciona en Raspbian (no lo he probado en ningún otro sistema). Además, después de investigar este problema, no he visto el uso de mvuna solución mencionada en ningún otro lugar. De hecho, según mi comprensión de cómo funcionan los permisos, tiene sentido que mvfalle cuando lo intenté. ¿Me estoy perdiendo de algo? ¿O tal vez ha cambiado esta funcionalidad? @Gilles @PaulHooper
fvgs
@fvgs Nada ha cambiado, pero su situación puede tener permisos diferentes de este. Le sugiero que haga una nueva pregunta (en Unix y Linux en lugar de Falla del servidor, ya que esta pregunta probablemente se consideraría fuera de tema si se hiciera en SF ahora) y proporcione todos los detalles de su situación.
Gilles 'SO- deja de ser malvado'
@Gilles ¿Podría indicarme alguna documentación, referencia o mención del comportamiento que describió mv? Puedo usar mvpara cambiar el nombre del directorio de barras. Lo que significa que mvtiene éxito siempre que no intente mover la barra fuera del directorio actual o en cualquier otro directorio. Pero el ejemplo que diste (que mueve la barra hacia arriba de un directorio) no funciona para mí (permiso denegado). ¿El ejemplo que dio asume condiciones específicas diferentes a las especificadas en la pregunta?
fvgs
@fvgs Mi ejemplo no mueve barun directorio hacia arriba, lo mueve a un directorio de su propiedad. garbagepuede estar en cualquier parte del mismo sistema de archivos, no necesariamente un hermano de foo.
Gilles 'SO- deja de ser malvado'
0

La única forma de evitar esto sería usar un setgid o setuid en el directorio padre o usar una ACL.

Establezca el directorio setgid con

chmod g+s foo

Establezca una ACL predeterminada con

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

Esto lo establece como la ACL predeterminada en esta ruta. ¡Debe montar el sistema de archivos que contiene esta ruta con la opción acl!

Ahora dime por qué crees que quieres esto.

wzzrd
fuente
Bueno, el problema es de consistencia. Nada me impide eliminar un archivo o un directorio vacío propiedad de otro usuario en un directorio que tengo, pero si no está vacío, no puedo eliminar mi propio directorio.
Alex B
Si ese es el caso, usaría una de las opciones que proporcioné. Funcionarán bien para ti.
wzzrd
A menudo uso varias cuentas en mi escritorio (una de las cuales es la cuenta "principal no root"). También puedo obtener tal situación cuando se make installinicia desde la raíz comienza a construir algo.
Vi.
setgid en el directorio padre no ayuda. Después de hacerlo como root, cd ~user && mkdir qqq && touch qqq/qqqno puedo eliminar qqq del usuario por chmod g+s .y rm -Rf qqq.
Vi.
Mmm. Eso es probablemente una cuestión de máscaras entonces. Si su directorio es 775, es setgid y su umask es 0002, entonces los archivos se pueden escribir para el grupo y, por lo tanto, se pueden quitar. Pero, es cierto, no funciona con umask 0022 (que es principalmente el predeterminado). Debería haber dicho eso. ¿Has probado la opción acl?
wzzrd