it-swarm-es.tech

Terminal: enumera todos los directorios para los que un usuario o grupo tiene permiso de escritura

Me gustaría enumerar todos los directorios para los que un usuario o grupo tiene permisos de escritura.

Encontré esta pregunta en ServerFault , pero se dirige a un servidor de Windows, así que estoy optimista de que hay algo mejor para nosotros en la comunidad de Linux. Al mismo tiempo, me doy cuenta de que hay un giro recursivo en esta pregunta que puede hacerla imposible sin un script de larga ejecución.

Soy consciente de los siguientes comandos útiles:

  • Liste todos los grupos: cut -d : -f 1 /etc/group
  • Lista de todos los usuarios: cut -d : -f 1 /etc/passwd
  • Obtener el directorio de inicio de un usuario: getent passwd user-name| cut -d: -f 6
  • Este script que enumera cada usuario y sus tareas grupales
  • Obtenga permisos y detalles de usuario/grupo sobre el contenido de la carpeta: ls -la

Sin embargo, cuando no tengo idea de cuál es el propósito de un usuario, sería bueno obtener una lista de TODOS los directorios para los que tienen permiso de escritura y comenzar a buscar desde allí. Si nada más, es una auditoría súper útil ...

Si me ayuda a entender mi propósito, heredé (¿o al menos estoy cuidando niños?) Un par de sistemas después de que nuestro SysAdmin tomara una nueva posición. Así que he estado tratando de entender la evolución de estos dos sistemas, como qué software está instalado y dónde (..ugh), dónde viven varios archivos de configuración y ahora, qué grupos y usuarios diferentes se han creado, incluidos los directorios en los que pueden escribir. Por lo general, puedo encontrar comandos de terminal útiles aquí en askubuntu, pero al no encontrar este, pensé en seguir adelante y preguntar.

El sistema exacto es Ubuntu 10.04.2, pero también admitimos Ubuntu 12.04.5, por lo que la solución más independiente de la versión sería la mejor. Gracias de antemano por cualquier ayuda.


[Actualización: resultados iniciales de las dos respuestas rápidas]

Vale la pena señalar que he iniciado sesión como root para estos, y / era mi directorio de trabajo. Además, tomaron una cantidad de tiempo comparable para correr.

El comando combinado de @ Rinzwind obtuvo el siguiente resultado en aproximadamente 5,5 minutos.

[email protected]:/# Sudo find -type d \( \( -user ftpgisdata -perm /u=w \) -o \( -group ftpgisdata -perm /g=w \) -o -perm /o=w \)
./tmp
./tmp/.ICE-unix
./tmp/.X11-unix
find: `./proc/6594/task/6594/fd/5': No such file or directory
find: `./proc/6594/task/6594/fdinfo/5': No such file or directory
find: `./proc/6594/fd/5': No such file or directory
find: `./proc/6594/fdinfo/5': No such file or directory
./var/tmp
./var/lib/php5
./var/crash
./var/lock
./home/ftpgisdata
./home/ftpgisdata/.ssh
./home/ftpgisdata/.cache
./home/sitename-i-changed.com/wp-content/profile-pics
./dev/shm

El comando revisado de @ Oli obtiene algo muy similar, también en aproximadamente 5,5 minutos.

[email protected]:/# Sudo find / -type d -print0 | Sudo -u ftpgisdata xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
find: `/proc/15541': No such file or directory
find: `/proc/15542': No such file or directory
find: `/proc/15543': No such file or directory
find: `/proc/15567': No such file or directory
find: `/proc/15568/task/15568/fd/5': No such file or directory
find: `/proc/15568/task/15568/fdinfo/5': No such file or directory
find: `/proc/15568/fd/5': No such file or directory
find: `/proc/15568/fdinfo/5': No such file or directory
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm

La respuesta de @PeterCordes también arrojó resultados similares en aproximadamente 5,5 minutos.

[email protected]:~# username_to_check=ftpgisdata base_dir=/   # for example
[email protected]:~# Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
/proc/7159/task/7159/fd
/proc/7159/fd
/proc/7159/map_files
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm
7
elrobis

Es difícil determinar qué puede hacer un usuario si no eres ese usuario. Puede probar varias cosas (es propietario, mismo grupo, etc.) pero puede aplicarse ACL, puede que no haya permisos en el montaje, quién sabe. Es dificil.

Si puedes convertirte en ese usuario, puedes test -w <path> para ver si pueden escribir. Esto no es tan rápido como solo mirar el inodo, pero es posible con Sudo.

Sudo -u oli test -w <path> && echo "HOORAY"

Entonces podemos ponerlo en el back-end de find. En lugar de usar -exec para cambiar al usuario oli una y otra vez (ver revisiones anteriores), canalizamos todo a una instancia de xargs que se ejecuta como oli. Esto es mucho más rápido.

Sudo find / -type d -print0 | Sudo -u oli xargs -0 -I{} sh -c 'test -w "$0" && echo "$0"' {}

Una versión algo optimizada (pero visualmente más flácida) implica minimizar la cantidad de subcarteado que realiza el xargs canalizando un flujo de rutas en un bajo número de subcapas bash. Esto es indudablemente más rápido para grandes búsquedas.

Sudo find / -type d -print0 | Sudo -u oli xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
7
Oli

En el chat llegamos a las siguientes instrucciones para usuarios y grupos:

Sudo find / -type d -user rinzwind -perm /u=w
Sudo find / -type d -group rinzwind -perm /g=w
Sudo find / -type d -perm /o=w

O combine los tres en uno:

Sudo find -type d \( \( -user rinzwind -perm /u=w \) -o \( -group rinzwind -perm /g=w \) -o -perm /o=w \)

Sin el/it busca el directorio actual.

Tomó menos de 2 segundos con 67 Gb de datos en mi sistema;)

4
Rinzwind

Respuesta en construcción, por favor sea paciente

Prueba para uno mismo

Uno puede probar los permisos de escritura para sí mismo con el siguiente código:

[ -w /home/$USER ] && echo yes # using home directory as example

Usando la bandera -d para la prueba, podemos probar si algo es un directorio.

Sabiendo todo eso y find podemos hacer

find /home/ -print0 2> /dev/null | while IFS=""  read -r -d "" file ; do [ -d "$file"  ] &&  [ -w "$file" ]  && echo "$file" is writeable ; done

Nota al margen: Obviamente, si obtiene errores de permiso con find, no puede leer ese archivo, por lo tanto, no hay razón para generar esos errores, por lo tanto, la redirección a dev null. Obviamente, esto no funcionará si queremos averiguar los permisos para los usuarios que no sean uno mismo, y tenga en cuenta que/home es solo un ejemplo aquí. Tales carpetas como /var tienen carpetas compartidas entre múltiples usuarios

Prueba para otros

Se puede usar stat por cada archivo que find encuentra y filtrar con awk

 find /var -type d -exec stat --format '%g %n'  {} \; 2> /dev/null | awk '$1=='1000'{print}' 

Aquí estoy filtrando la identificación numérica de mi propio usuario, 1000, pero podría ser la identificación de cualquier usuario. Por supuesto, uno puede jugar con opciones, use el nombre del grupo en lugar de identificadores numéricos. Es algo muy flexible y adaptable al propósito que necesita.

Pequeños ajustes

Así que me di cuenta de que mencionas haber iniciado sesión como root. Aquí hay una salida de mi comando, donde estadifico archivos e imprimo su grupo y nombre de archivo, luego filtro usando AWK por el nombre de grupo apropiado.

$ find /proc -type d -exec stat --format '%G %n'  {} \; 2> /dev/null  | awk '$1=="syslog"{print}'
syslog /proc/560
syslog /proc/560/task
syslog /proc/560/task/560
syslog /proc/560/task/560/net
syslog /proc/560/task/560/attr
syslog /proc/560/task/562
syslog /proc/560/task/562/net
syslog /proc/560/task/562/attr
syslog /proc/560/task/563
syslog /proc/560/task/563/net
syslog /proc/560/task/563/attr
syslog /proc/560/task/564
syslog /proc/560/task/564/net
syslog /proc/560/task/564/attr
syslog /proc/560/net
syslog /proc/560/attr
^C
2

Si tiene GNU find, puede usar la prueba -writable (tenga en cuenta la ortografía, no es writeable). Eso usa la llamada al sistema access(2) en lugar de solo tratar de resolver las cosas mirando los permisos, por lo que funciona correctamente con las ACL. (Pero podría romperse en NFS con asignaciones de ID).

También encontrará directorios que el usuario puede escribir gracias a ser miembro de un grupo secundario. (por ejemplo, un directorio en /usr/local grabable por los usuarios en el grupo admin, o algo así como chown root:users /data/share && chmod 2775 /data/share, donde algunas cuentas son miembros del grupo users).

username_to_check=peter base_dir=/   # for example
Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX

Habrá errores cuando find encuentre directorios en los que el usuario no pueda descender, por lo que redirigiremos los errores a /dev/null.

Esto no encontrará ningún directorio que se pueda escribir pero dentro de directorios sin permiso de ejecución, porque find ejecutándose ya que el usuario no puede atravesar los directorios superiores. Sin embargo, si un proceso que poseen se inicia dentro de dicho directorio, podrán escribir con rutas relativas. (o obtienen un descriptor de archivo abierto para dicho directorio, pueden usar openat(2)). pwd no funcionará si no tienen permiso de ejecución en uno de los componentes del directorio de la ruta completa, por lo que no es una configuración común.

Esto también pierde directorios que se pueden escribir que están dentro de directorios ejecutables pero no legibles . Para evitar esas limitaciones, probablemente ejecute find -type d como root y use find -writable como usuario para verificar las rutas resultantes. Eso podría ser más eficiente que un bucle de Shell usando [ -w "$f" ].

POSIX find(1) tiene muchas menos opciones que GNU find. Si su script tiene que ser portátil para POSIX, probablemente sea más fácil canalizarlo a otra cosa que verifique los permisos, como un Shell con [ -w "$f" ] (vea la otra respuesta que sugiere esto).

2
Peter Cordes