¿Por qué un archivo con 400 permisos es visto como escribible por el usuario root pero de solo lectura por el usuario?

10

Si creo un archivo como un usuario sin privilegios, y cambio el modo de permisos a 400, ese usuario lo ve como de solo lectura, correctamente:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

Todo está bien.

Pero luego aparece la raíz:

# [ -w somefile ] && echo rw || echo ro
rw

¿Que demonios? Claro, la raíz puede escribir en archivos de solo lectura, pero no debería convertirse en un hábito: las mejores prácticas tenderían a dictar que debería ser capaz de probar el bit de permiso de escritura, y si no es así, se configuró de esa manera por una razón.

Supongo que quiero entender por qué sucede esto y cómo puedo obtener un código de retorno falso al probar un archivo que no tiene el bit de escritura establecido.

Rico
fuente
por cierto estoy usando tanto RHEL6 ( 4.1.2(1)-release) como RHEL7 ( 4.2.46(2)-release).
Rico
16
"Las mejores prácticas tienden a dictar que debería ser capaz de probar el bit de permiso de escritura, y si no es así, se estableció de esa manera por una razón". - En realidad, la mejor práctica es "no ejecutar cosas como root". Si está ejecutando como root, ya ha decidido omitir las verificaciones de permisos. La reinstalación manual de esas verificaciones de permisos en el espacio de usuario es una receta para el desastre .
Kevin
@ Kevin Bueno para ti si puedes ejecutar cosas sin privilegios. Esto es para manipular /etc/dhcp/dhcpd.conf, que es propiedad de root. Estoy usando el suministrado por el vendedor dhcpd. Desastre total, ¿eh? El archivo se registró en RCS, estoy automatizar el uso de rcsdiff, ciy coporque tenemos operadores que deben operar .... La comprobación de bits de permiso ( -wcomo se detalla en test(1)) iba a ser una primera línea de falla, trabajando sobre la base de que ci -udeja un archivo de solo lectura. Estoy abandonando eso y yendo directamente a rcsdiff -qcomprobar $?. dhcpd¿ Desastroso ? Que sería propiedad de dhcpd.
Rico
1
Es un desastre potencial porque ahora tiene dos implementaciones diferentes de comprobaciones de permisos: una en el núcleo y otra en el espacio de usuario. Peor aún, esas implementaciones ni siquiera tienen la intención de producir resultados idénticos, por lo que no puede simplemente probarlas entre sí. Por lo tanto, ahora tiene dos rutas de acceso que deben bloquearse y asegurarse independientemente una de la otra.
Kevin
@Kevin Claro, no producen resultados idénticos y no estaban destinados a hacerlo (a pesar de la escasez de detalles en las páginas de manual), pero quiero comprobar explícitamente el bit de permiso de escritura ; y las páginas de manual para bashy testme llevaron a creer que para eso [ -wes.
Rico

Respuestas:

26

test -waka [ -wno verifica el modo de archivo. Comprueba si se puede escribir. Para root, lo es.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

La forma en que probaría sería hacer una comparación bit a bit contra la salida de stat(1)(" %a Derechos de acceso en octal").

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Tenga en cuenta que el subshell $(...)necesita un 0prefijo para que la salida de statsea ​​interpretada como octal por (( ... )).

Patricio
fuente
Gracias por ser conciso. Buen uso de (( ... & ... )). Un error tipográfico corregido :-)
Rico
Haga que 3 ... No es ifnecesario, la salida de permisos octales %ano es %d, y (( ... ))necesita un prefijo 0para interpretar la salida de statcomo octal.
Rico
@Patrick my man statdice "% d número de dispositivo en decimal", pero lo que queremos son los "derechos de acceso", ¿no? Su punto sobre la necesidad del prefijo 0 está bien hecho, pero supongo que solo tenemos que ponerlo allí :).
sourcejedi
2
stat -c 0%a...
sourcejedi
@sourcejedi ack, tienes razón. Por alguna razón, estaba pensando que% d eran derechos de acceso en decimal. Restaurado la edición. gracias :-)
Patrick
30

Creo que has entendido mal lo que -whace. No verifica si el archivo tiene "Permisos de escritura", verifica si el usuario que invoca puede escribir el archivo .

Más específicamente, llama access(2)o similar.

por ejemplo, si tiene un script, if [ -w /etc/shadow ]entonces si ejecuta straceel script puede ver una línea similar

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

Como rootpuede escribir en el archivo, devuelve 0.

por ejemplo, como usuario normal:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

Como raíz

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

Esto, a pesar del hecho de que /etc/shadowtiene permiso 000en mi máquina.

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

Ahora lo que quieres hacer se vuelve interesante y no es tan simple.

Si desea verificar los permisos simples, verifique la lssalida, o llame stato similar. Pero tenga en cuenta que las ACL pueden anular estos permisos. El hecho de que un archivo tenga permiso 400 no impide que se pueda escribir ...

Stephen Harris
fuente
No, "malentendido" sería leer mal las páginas de manual para -w: test(1)es explícito: "existe el ARCHIVO y se otorga permiso de escritura ", no " el usuario actual puede escribir el archivo ". Nada sobre anular permisos, ni ACL. bash(1)es cauteloso: "Verdadero si el archivo existe y se puede escribir ". ksh(1)hace una sugerencia sutil hacia travesuras: "-w archivo // Verdadero, si el archivo existe y el proceso actual lo puede escribir ". zsh(1)difiere test(1), zshmisc(1)está redactado como ksh(1), y zshexpn(1)detalla algunos globings basados ​​en permisos interesantes. csh(1)es hilarantemente breve: "Acceso de escritura".
por cierto: acepté la respuesta de Patrick, 1. porque no respondiste adecuadamente la pregunta inicial: ¿cómo puedo obtener un código de retorno falso al probar un archivo que no tiene el bit de escritura establecido? y 2. debido a la presunción sarcástica inicial suponiendo que entendí mal las páginas del manual.
Rico
3
@Rich La forma en que leí esto, creo que tus comentarios también son un poco sarcásticos. No estoy diciendo que nada de lo que escribiste esté mal, solo que probablemente iría mejor si se expresara de una manera más educada.
David Z
3
"Creo que has entendido mal ..." no es sarcástico. Sin embargo, su respuesta es 100% sarcástica.
barbacoa
@Rich Además, si bien las páginas de manual podrían no haber sido claras como el cristal, Stephen ha declarado que puede haber "entendido mal lo que -w hace ", y no lo que dicen las páginas de manual , donde el primero parece ser el caso, de ahí la pregunta
Sebi
1

El usuario root puede hacer lo que quiera, los permisos de archivo "normales" no son una limitación. No ejecutará directamente un archivo simple sin ningún permiso de ejecución, solo por un poco de seguro contra la práctica de tiro al blanco.

vonbrand
fuente