Quiero encontrar archivos que un usuario en particular no podrá leer.
Suponga que el nombre de usuario es "user123" y están en un grupo llamado "user123". Quiero encontrar archivos que, si son propiedad del usuario123, tienen activado u + r; en caso de que, si el archivo es el usuario del grupo 123, debería tener activado g + r; si no puede tener o + r encendido.
Como GNU find tiene "legible", podría hacer esto:
sudo -u user123 find /start ! -readable -ls
Sin embargo, el proceso debe ser ejecutado por un usuario que no tiene acceso a sudo. Por lo tanto, intenté esto: (no marca o + r pero eso no es importante en este punto)
find /start \( -user user123 ! -perm -u=r \) -o \( -group user123 ! -perm -g=r \) -ls
pero enumera este archivo:
272118 4 -rw------- 1 user123 user123 3243 Jul 3 19:50 /start/blah/blah/file.txt
Este archivo es el único archivo /start
que pertenece al usuario123 con g=r
desactivado. Es como si find está interpretando el -u=r
as -g=r
.
Decidí intentar invertir la lógica y probar not ( truth )
en su lugar:
find /etc/puppet ! \( \( -user puppet -perm -u=r \) -o \( -group puppet -perm -g=r \) -o \( -perm -o=r \) \) -ls
¡Eso funciona!
¿Por qué find
falló el original ? ¿Es un error en find
(poco probable) o la lógica es incorrecta?
Actualización: me equivoqué de lógica. Como se señala a continuación, ya que! (A || B || C) == (! A &&! B &&! C) estas son las dos declaraciones equivalentes:
find /start ! \( \( -user user123 -perm -u=r \) -o \( -group user123 -perm -g=r \) -o \( ! \( -user user123 -o -group user123 \) -perm -o=r \) \) -ls
find /start ! \( -user user123 -perm -u=r \) ! \( -group user123 -perm -g=r \) ! \( ! \( -user user123 -o -group user123 \) -perm -o=r \) -ls
Mi objetivo no era tener que probar el usuario / grupo dos veces. Lo que realmente necesito es una estructura if-then-else más complicada, que probablemente solo sería posible si hubiera un operador -xor. Podría construir un xor a partir de y / o / no, pero sería más complejo que las dos soluciones anteriores.
puppet
tiene acceso a un archivo con--wxrwxrwx puppet puppet
.Respuestas:
La lógica está mal. Está pensando que este archivo no debería haberse incluido en la lista porque es propiedad
user123
y tiene elr
conjunto de bits del usuario . Sin embargo, aparece en la lista porque coincide con el segundo criterio (es propiedad del grupouser123
y tiene elr
bit unset no establecido).Su segunda versión funciona debido a una de las leyes de De Morgan : negar el OR lógico de un grupo de declaraciones es lógicamente equivalente a AND la negación de las declaraciones individuales. En otras palabras:
Entonces, el trabajo
find
está buscando un archivo queuser123
y legible por dicho usuario) Yuser123
y legible por dicho grupo) Ymientras que el primero
find
busca un archivo queuser123
y no puede ser leído por dicho usuario Ouser123
y no es legible por dicho grupo O (si lo ha completado)Por lo tanto, un archivo que coincida con CUALQUIERA de los 3 criterios anteriores (y no necesariamente todos) aparecería como lo ha visto.
Editar
Por cierto (después de ver su perfil), soy un gran admirador de su libro O'Reilly :)
fuente
( !A && !B && !C )
pero me mudé!
al interior de cada parte, lo que no es válido. ¡Gracias!Hay muchas más cosas a tener en cuenta para verificar si un usuario tiene acceso a un archivo a través de una ruta determinada:
A menos que realmente cambie todos los uids y gids a los del usuario y compruebe, es muy difícil implementar la misma lógica que lo que hace el sistema.
Con zsh, podría hacer (como root):
O con
perl
:Es decir, en ambos casos, descienda el árbol de directorios
root
pero pruebe el acceso a los archivos como el usuario correspondiente.Ejecutar
find -readable
comosome-user
no lo hará en los casos ya que no podrá pasar los directorios para los que el usuario no tiene acceso o no tiene permiso de lectura (pero posiblemente acceso).Incluso cuando solo considera el permiso y la propiedad del archivo en sí (y no las ACL o los componentes de la ruta ...), necesita al menos (aquí la sintaxis de GNU):
La idea es que si el archivo es propiedad del usuario, todos los demás permisos son irrelevantes. Si no es así, si el archivo es propiedad de un grupo de cualquiera de los grupos de usuarios, entonces el permiso "otro" es irrelevante.
fuente
access()
porque usa el mismo código de kernel queopen()
. Porsudo -u user123 find /start -readable
lo tanto, es la mejor solución sisudo
es una opción.sudo -u user123 find -readable
, no informará archivos en directorios que no puede ingresar, o en directorios que no puede leer (por lo que habrá falsos negativos y falsos positivos). Es por eso que se sugiere emplearzsh
para descender el árbol de directorios como root y haceraccess()
([ -r ... ]
) como el usuario actual (ajuste$USERNAME
dezsh
cambios todos los UID y GID comosudo
lo haría).