Accidentalmente chmod -R + x en un directorio. ¿Cómo restauro los permisos correctos?

20

Bueno, para ser específicos, lo fue chmod -R 755. Ahora cada archivo es ejecutable, lo que no quiero. Estoy pensando que debería mirar los dos primeros bytes de cada archivo #!, pero ¿esto cubrirá todo? ¿Debería usar filepara mirar todo y basar mi decisión en eso? O, más probablemente, ¿hay una forma aún mejor de hacer esto?

¿Cuál es la forma preferida de ir recursivamente a través de un directorio y establecer -x en archivos que no deben ser ejecutables?

Larry Wang
fuente
¿Hiciste esto en /otro directorio?
gvkv
1
@gvkv: No /, un directorio que me pertenece por completo.
Larry Wang
1
@Larry en el futuro probablemente deberías usar alguna variante de + x en lugar de violar todos los permisos y posiblemente causar escrituras en todos los archivos.
xenoterracide
@xenoterracide: De acuerdo. Lo que realmente quería era darle al grupo los mismos permisos que a mí (¡lo que terminó sucediendo!), Simplemente no pensé lo suficiente antes de escribir.
Larry Wang
¿De cuántos archivos estamos hablando? ¿Cuántos deberían ser ejecutables? ¿Hay alguna forma de distinguir los nombres de archivo?
David Thornley

Respuestas:

15

No hay una bala mágica aquí. Los permisos llevan información que no siempre es redundante.

Si hubiera hecho esto en un directorio del sistema, su sistema estaría en muy mal estado, porque tendría que preocuparse por los bits setuid y setgid, y por los archivos que no deberían ser legibles en todo el mundo, y por los archivos que se supone que se pueden escribir en grupo o en el mundo.

En un directorio por usuario, debe preocuparse por los archivos que no deberían ser legibles en todo el mundo. Nadie puede ayudarte allí.

En cuanto a la capacidad de ejecución, una buena regla general sería hacer que todo lo que no parece que pueda ejecutarse, sea no ejecutable. El kernel puede ejecutar scripts cuyos primeros dos bytes son #!, binarios ELF cuyos primeros cuatro bytes son \x7fELFdonde \x7festá el byte con el valor 12 y algunos tipos de archivos más raros (a.out, cualquier cosa registrada con binfmt_misc). Por lo tanto, el siguiente comando debería restaurar sus permisos a un estado razonable (supone bash 4 o zsh; de lo contrario, use findpara recorrer el árbol de directorios; advertencia, escrita directamente en el navegador):

for x in **/*; do
  if ! [ -f "$x" ]; then continue; fi # skip all but regular files
  case $(head -c 4 "$x") in
    "#!"??) :;; # skip script
    "\x7fELF") :;; # skip ELF executable
    *) chmod a-x "$x";;
  esac
done

Tenga en cuenta que hay una manera simple de hacer una copia de seguridad y restaurar los permisos de un árbol de directorios, en Linux y posiblemente en otros dispositivos compatibles con ACL:

getfacl -R >saved-permissions
setfacl --restore=saved-permissions
Gilles 'SO- deja de ser malvado'
fuente
¡Gracias! Afortunadamente, creo que todo cae en estas dos categorías. Si esto falla algo, puedo tratarlo más tarde.
Larry Wang
Tenga en cuenta que **/*requiere globstar.
Chris Down
Recomiendo dos cambios a este script. Uno, use en findlugar de globstar; dos, en lugar de mirar la cabeza, use el filecomando para ver qué es y bifurcarse desde allí.
Shadur
@Shadur findes menos confiable que globstar, globstares preferible en casi todos los casos.
Chris Down
1
@Gilles Preferible como en "si lo tiene, es muy superior", no solo es más rápido, también es más confiable (y no tiene SNAFU inesperados).
Chris Down
6

Creo que querrás algo como

find dir -type f -exec chmod ugo-x '{}' +

Esto busca todos los archivos regulares, recursivamente en dir, (excluye directorios y dispositivos) y elimina el bit ejecutable.

Comenzaría aquí y luego trabajaría para crear archivos que se supone que son ejecutables, ejecutables.

Lo siguiente debería funcionar exactamente como lo solicitó (encontrará todos los archivos normales, agréguelos por #! Y luego elimine los bits x si no se encuentran)

find . -type f | xargs grep -L #! | xargs chmod ugo-x

posiblemente una mejor versión de lo anterior (menos tuberías)

find . -type f -exec grep -L #! '{}' + | xargs chmod ugo-x 
xenoterracida
fuente
3
Haga eso grep -L '^#!'al menos (las comillas son necesarias y se ^restringe a la coincidencia al comienzo de la línea), pero sigue siendo demasiado permisivo ya que coincide #!en cualquier línea. El uso xargsfallará con los nombres de archivo que contengan espacios o comillas; uso xargs -d '\n'(requiere GNU xargs).
Gilles 'SO- deja de ser malvado'
0

Bueno, sin una línea shebang, el archivo se ejecutará como un script de shell, nominalmente con /bin/sh. Su idea es un buen comienzo y suponiendo que el directorio en cuestión no contenga archivos de misión crítica, probablemente no exista mucho riesgo de ejecutar algunos grepy chmodcombo. Puede encontrar falsos positivos, es decir, archivos con una línea shebang que no están destinados a tener su bit ejecutable establecido pero sin conocer más información sobre el propósito de lo que hay en el directorio, solo usted puede decidir si eso representa una amenaza existencial significativa para su sistema y / o datos.

gvkv
fuente
No me preocupan tanto los falsos positivos como los falsos negativos. Hay binarios con los que no creo que comience #!.
Larry Wang