¿Cómo verificar si un usuario puede acceder a un archivo determinado?


60

* Los permisos de usuario de nix son realmente simples, pero las cosas pueden complicarse cuando tienes que tener en cuenta todo el acceso al directorio principal antes de llegar a un archivo determinado. ¿Cómo puedo verificar si el usuario tiene suficientes privilegios? Si no, ¿qué directorio está negando el acceso?

Por ejemplo, suponga un usuario joey el archivo /long/path/to/file.txt. Incluso si file.txtfue modelado a 777, Joe todavía tiene que poder acceder /long/, y luego /long/path/y /long/path/to/antes. Lo que necesito es una forma de verificar esto automáticamente. Si joeno tiene acceso, también me gustaría saber dónde se le ha denegado. Quizás él pueda acceder /long/, pero no /long/path/.

Respuestas:


71

Puedes usar

namei -m /path/to/really/long/directory/with/file/in

que generará todos los permisos en la ruta en una lista vertical.

o

namei -l /path/to/really/long/directory/with/file/in

para enumerar todos los propietarios y los permisos


2
Esta debería ser la respuesta correcta. De hecho, el uso le namei <path> || exit 1permite detectar un problema de permisos con mucha facilidad en un script.
— lorenzog

55
no responde directamente si joe tiene acceso al archivo.
— jfs

15

Puedes usar bash para hacer esto.

$ cat check-permissions.sh
#!/bin/bash
file=$1
# Handle non-absolute paths
if ! [[ "$file" == /* ]] ; then
    path=.
fi
dirname "$file" | tr '/' $'\n' | while read part ; do
    path="$path/$part"
    # Check for execute permissions
    if ! [[ -x "$path" ]] ; then
        echo "'$path' is blocking access."
    fi
done
if ! [[ -r "$file" ]] ; then
    echo "'$file' is not readable."
fi
$ ./check-permissions.sh /long/path/to/file.txt

Para verificar esto para un usuario específico, puede usar sudo.

sudo -u joe ./check-permissions.sh /long/path/to/file.txt

sudo -u joe script. Aquí script es el nombre del archivo de script ¿verdad? Entonces, ¿le estás diciendo a sudo que actúe como Joe estaba llamando al guión?
— tgkprog

Precisamente. He modificado mi respuesta para aclarar eso.

Hice una ligera modificación en mi script para manejar rutas no absolutas.

@EvanTeitelman Con una ruta absoluta, ¿querías inicializar pathpara estar vacío? o /?
— Gilles 'SO- deja de ser malvado'

@Gilles: quise decir que estuviera vacío. En el ejemplo, pathse establece por /longprimera vez alrededor del ciclo, lo cual es correcto. ¿Debo establecer pathnada explícitamente ( path=)? Además, gracias por simplificar mi uso de tr.

3

Como obtuve de su pregunta, debe verificarlo para diferentes usuarios (no solo Joe), por lo que en ese caso la forma más fácil es verificarlo de manera recursiva a través de sudo de esta manera:

FILE=$1 ; T_USER=$2 ;
if sudo -u $T_USER [ -r "$FILE" ] ; then
    echo "original file $1 is readable for $T_USER"
else
    while sudo -u $T_USER [ ! -x "$FILE" ] ; do FILE=$(dirname "$FILE") ; done
    echo "only $FILE is readable for $T_USER"
fi

uso:

./script.sh /long/path/to/file.txt joe

Joe necesita ejecutar permisos en los directorios, no leer permisos.

@EvanTeitelman sí, tienes razón. Fijo.
— prisa el

@rush intenté probarlo utilizando el siguiente archivo: /root/test/test.txt (permisos son 0755, 0700y 0777). Emití ./script.sh /root/test/test.txt joey se hizo eco original file /root/test/test.txt is readable for joe. Además, al intentar esto, escribí mal el directorio de prueba: ./script.sh /root/tst/test.txt joey se hizo eco original file /root/tst/test.txt is readable for joe. ¿Me perdí algo?
— Metalcoder

@Metalcoder lo siento, es mi culpa. Hubo una exclamación extra. Se ha eliminado ahora, puedes probarlo una vez más, debería funcionar bien ahora.
— prisa el

@ Rush funcionó! Esa exclamación adicional niega el resultado de -r $FILE, ¿verdad?
— Metalcoder

1

Aquí está mi intento de proporcionar esta funcionalidad. He optado por usar stat, un whilebucle, y dirname.

He creado este script walkdir.bash:

#/bin/bash

cwd="$1"
while [ "x$cwd" != x/ ]; do
  info=`stat "$cwd" |grep "Access: ("`
  printf "%s : %s\n" "$info" "$cwd"

  cwd=`dirname "$cwd"`;
done

Lo ejecutas así:

$ walkdir.bash "/home/saml/blog/vmware_networking_tutorial/url.txt"
Access: (0664/-rw-rw-r--)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial/url.txt
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog
Access: (0700/drwx------)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root) : /home
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.