En un comando `sudo find`, ¿cómo me aseguro de que el comando` -exec` se ejecute como usuario normal?

10

Estoy tratando de hacer que el siguiente comando funcione de manera que el process_pathsscript no se ejecute con privilegios elevados. ¿Hay alguna forma de hacer esto?

sudo find /path/ -exec process_paths '{}' \+

Aquí /path/tiene algunos archivos que no tienen permiso de lectura para el usuario normal. El script process_pathssolo necesita los caminos.

pii_ke
fuente
... -exec sudo -u user process_paths {} \+
Satō Katsura
@SatoKatsura a veces esto falla con sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke
1
Sí, vea la nota sobre la SUDO_COMMANDvariable en find. . [^.] * -tipo f -print0 | xargs -0 sudo chmod 664; no funciona
Stéphane Chazelas
2
Si desea que los -execcomandos se invoquen como su usuario, ¿por qué lo está findutilizando sudoen primer lugar?
marcelm
2
@marcelm Creo que la última oración de la pregunta responde a la tuya.
Hola,

Respuestas:

16

En los sistemas que lo admiten (GNU y muchos otros), puede hacer lo siguiente:

sudo find /path/ -print0 | xargs -r0 process_paths

xargsno se ejecuta debajo sudo, por lo que todavía tiene los uids / gids originales y también el entorno original (en el sentido más amplio), no el modificado por sudo.

process_pathssin embargo, stdin termina siendo modificado (dependiendo de la xargsimplementación, está abierto /dev/nullo comparte pipedesde sudo/ find.

Para evitar eso (con GNU xargsy shells como ksh, zsho bashque admitan la sustitución del proceso), puede hacer lo siguiente:

xargs -r0a <(sudo find /path/ -print0) process_paths

Con zsh:

sudo zsh -c '
   files=(/path/**/*(D))
   USERNAME=$SUDO_USER
   autoload zargs
   zargs $files -- process_paths'

En zsh, la asignación de un nombre de usuario a la $USERNAMEvariable especial, establece los uids, gids a los del usuario correspondiente en la base de datos de usuarios como sudo -u "$SUDO_USER"lo haría.

Podrías hacerlo:

 sudo sh -c '
   exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'

Pero debido a que sudopasa una $SUDO_COMMANDvariable de entorno (que contiene la concatenación de los argumentos con espacios) a process_paths, la lista de archivos termina pasándose dos veces, lo process_pathsque significa que es probable que se alcance el límite del tamaño máximo de args + env si hay un gran Número de archivos.

Con la mayoría de las suimplementaciones, debería poder hacer:

 sudo sh -c '
   exec find /path/ -exec su "$SUDO_USER" -c '\''
     exec "$0" "$@"'\'' process_paths {} +'

aunque como suno tiene el mismo problema.

Stéphane Chazelas
fuente
1

Puedes usar sudo:

sudo find <directory> -exec sudo -u <normal_user> <command> {} \;

Pero como se dijo en un comentario, aparentemente puede fallar si el {} es demasiado largo para sudo.

Oye
fuente