
Estaba usando Vim el otro día como siempre, cuando noté algo extraño. Esto es lo que hice:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
Luego hice un cambio, guardé y salí con :wq
. Muy normal. Entonces, sin embargo:
~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile
Entonces root debería tener acceso r/w y todos los demás solo deberían haber leído. Edite el archivo, intente guardarlo, no puede. Impresionante, funcionando según lo previsto. Sin embargo, si guarda con :w!
, vim de alguna manera cambia la propiedad del archivo a nombre de usuario: grupo de usuarios y el archivo se guarda. Incluso si haces esto:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
Puedeaúnsobrescribir con :w!
! ¿Lo que está sucediendo? ¿Cómo puede vim violar las leyes de propiedad y permiso de archivos de esta manera? Miré la página de ayuda en vim diciendo :help :w
y encontré esto:
:w[rite]! [++opt] Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.
No he podido escribir en un archivo en vim anteriormente cuando no debería, así que supongo que el verdadero centro de mi pregunta es, ¿cómo puedo hacer que vim no pueda editar un archivo y por qué no está basado en el archivo? permisos del sistema, como era de esperar, y ¿qué mecanismo usa vim para editar el archivo que otros editores (gedit, nano) no pueden usar?
EDITAR: La computadora en la que probé esto usa el kernel de Linux 3.15.5-2-ARCH. El número de versión de Vim es 7.4.373-1, y es el que instaló pacman
; no lo compilé desde cero con ninguna opción especial.
Respuesta1
Puedo ver que su ruta actual es ~
el directorio de inicio de su usuario. Debería tener permisos de escritura en ese directorio.
Piénselo de otra manera: si tiene permisos de lectura y escritura en el directorio, ¿qué le impide copiar el archivo, eliminar el anterior y cambiar el nombre del nuevo con permisos diferentes?
¡Esto es exactamente lo que hace vim!
Si ejecuta vim bajo strace, por ejemplo:
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid() = 1000
unlink("testfile") = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10) = 10
fsync(3) = 0
close(3) = 0
chmod("testfile", 0644) = 0
Según este registro, puedo adivinar el siguiente proceso:
Algunas comprobaciones de permisos anteriores (e chown
intentos, etc.) se omiten por brevedad.
open
Intenta abrir el archivo para escribir (falla: permiso denegado)lstat
Verifique el propietario del archivogetuuid
Verifique la ID de usuario actual para ver si coincide con el propietario del archivo.unlink
Elimine el archivo (esto está permitido porque tiene permiso de escritura en el directorio)open
Crea un nuevo archivo con el mismo nombrewrite
El contenido del archivo (leído antes, escribí algunas tonterías)fsync
Vacíe el archivo en el disco (no es realmente importante)close
chmod
Cambie los permisos del nuevo archivo para que se parezca al anterior; resulta que ahora tiene un nuevo propietario.