¿Los subdirectorios no vacíos de otro usuario están a salvo de ser eliminados en mi directorio?

¿Los subdirectorios no vacíos de otro usuario están a salvo de ser eliminados en mi directorio?

En la siguiente situaciónls -alh

total 0
drwxrwx--- 1 user http  20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http  10 Nov 30 08:08 empty-subdir
drwx------ 1 http http  12 Nov 30 08:08 non-empty-subdir

donde existen dos subdirectorios (que no son de mi propiedad), que enumero como:

sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..

sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http  0 Nov 30 08:08 subdir

La diferencia entre los dos subdirectorios es que el no vacío non-empty-subdircontiene una carpeta.

Mi pregunta es si es por diseño que al intentar rm -rfeliminar los subdirectorios obtengo resultados:

$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http  10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http  12 Nov 30 08:08 non-empty-subdir

Parece que el usuario con permisos de escritura en un directorio puede eliminar una entrada de un archivo o un subdirectorio vacío de algún otro usuario, pero no unno vacíosubdirectorio.

Una respuesta ideal a esta pregunta proporcionaría información como:

  • una confirmación de que el comportamiento descrito es reproducible en otras máquinas (y no meras peculiaridades de mi caja estropeada)
  • una justificación para explicar ese comportamiento (por ejemplo, ¿hay casos de uso?)
  • una descripción general si hay diferencias entre sistemas (BSD, Linux....)

Actualizar: Con respecto al comentario de Ipor Sircer, volví a probar el escenario, sin ninguna característica de ACL y es el mismo. Por lo tanto, modifiqué la pregunta para eliminar +es de los listados para no dar lugar a la idea de que el comportamiento podría estar relacionado con las ACL.

Respuesta1

Sólo se puede eliminar un directorio (con la rmdir()llamada al sistema) si está vacío.

rm -r direlimina el directorio y todos los archivos que contiene, comenzando con las hojas del árbol de directorios y subiendo hasta la raíz ( dir).

Para eliminar un archivo (con rmdir()for directorios y unlink()para otros tipos de archivos, o *at()variantes), lo que importa no son los permisos del archivo en sí sino los del directorio del que estás eliminando el archivo (cuidado con el tbit en los permisos, como para /tmp, añade más complicaciones a eso).

Antes que nada, en realidad no estás eliminando elarchivo, lo estás desvinculando de un directorio (y cuando es el último enlace que estás eliminando, el archivo termina siendo eliminado como consecuencia), es decir, estás modificando el directorio, por lo que necesitasmodificando(escribir) permisos para ese directorio.

La razón por la que no puedes eliminarlo non-empty-dires que no puedes desvincularlo subdirprimero, ya que no tienes derecho a modificarlo non-empty-dir. Tendría derecho a desvincularse non-empty-dirde su directorio de inicio ya que tiene permiso de escritura/modificación en ese, solo que no puede eliminar un directorio que no esté vacío.

En su caso, como lo señaló @PeterCordes en los comentarios, la rmdir()llamada al sistema falla con un ENOTEMPTYcódigo de error (Directorio no vacío), pero como no tieneleerpermiso para el directorio, rmni siquiera puede descubrir qué archivos y directorios (incluidos subdir) necesitaría desvincularse para poder vaciarlo (no es que pudiera desvincularlos si lo supiera, ya que no tiene permisos de escritura).

También puedes meterte en situaciones en las querm podríaelimine un directorio si pudiera descubrir qué archivos hay en él, como en el caso de un directorio de solo escritura:

$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied

Aún así, puedo eliminarlo porque sé que solo contiene un filearchivo:

$ rm dir/file
$ rmdir dir
$

También tenga en cuenta que con Unices modernos puede cambiarle el nombre non-empty-dir, pero en algunos como Linux o FreeBSD (pero no Solaris),nomuévalo a un directorio diferente, incluso si también tuviera permiso de escritura en ese directorio, como (creo que y para Linux, como lo sugiereel comentario para el código relevante) hacerlo implicaría modificar non-empty-dir(la ..entrada apuntaría a un directorio diferente).

Se podría argumentar que eliminar su empty-dirtambién implica eliminar las entradas ..y ., por lo tanto, modificarlo, pero aún así, el sistema le permite hacerlo.

Respuesta2

Al ignorar el posible cambio a través de las ACL, puedo confirmar este comportamiento para mi sistema (sin ACL).

El comportamiento observado es la consecuencia lógica de dos principios:

1) Los derechos de un directorio determinan quién puede cambiar el directorio, es decir, eliminar entradas en el directorio. Los derechos de las entradas en ese directorio no juegan ningún papel.

2) Eliminar un archivo requiere potencialmente eliminar y limpiar la información asociada, es decir, inodos, listas de asignación de bloques, etc. Es por eso que no puede eliminar un subdirectorio que no esté vacío sin haber limpiado todos los archivos que contiene, porque de lo contrario los archivos que contiene volvería inaccesible, pero la información asociada no se habría limpiado.

Por lo tanto, puede eliminar empty-subdir, porque tiene derechos para escribir en el directorio en el que se encuentra. No puede eliminar non-empty-subdir, porque no tiene derechos para limpiar primero los archivos contenidos en este subdirectorio.

Realmente no hay ninguna justificación o caso de uso para esto. Se podría haber integrado una limpieza recursiva de un subdirectorio en el kernel, pero el Unix original mantuvo todo simple, y la limpieza recursiva habría sido demasiado complicada cuando se puede lograr con una utilidad de espacio de usuario.

No puedo proporcionar una descripción general completa entre las diferentes versiones, pero este era el comportamiento en el Unix original, y esperaría que fuera el mismo en todas las versiones de Unix, y me sorprendería si hubiera una versión de Unix. que se comportó de manera diferente.

Respuesta3

Intenté reproducir lo que usted describe y ejecuté strace rm -rf ./nonempty. Lo que eso revela es lo siguiente:

unlinkat(4, "subdir", AT_REMOVEDIR)     = -1 EACCES (Permission denied)

y según el unlinkatmanual (que en Linux es el mismo unlink(2), énfasis añadido por mí):

EACCES No se permite el acceso de escritura al directorio que contiene el nombre de ruta para el UID efectivo del proceso, o uno de los directorios en nombre de ruta no permitió el permiso de búsqueda. (Ver también path_resolución(7).)

Dado que el directorio principal, nonemptyno otorga userpermiso x (búsqueda), tiene sentido según la EACCESdescripción que subdirno se puede eliminar.

información relacionada