Dans une commande `sudo find`, comment puis-je m'assurer que la commande` -exec` est exécutée en tant qu'utilisateur normal?


10

J'essaie de faire fonctionner la commande suivante de manière à ce que le process_pathsscript ne soit pas exécuté avec des privilèges élevés. Y a-t-il un moyen de faire cela?

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

Voici /path/quelques fichiers sans autorisation de lecture pour un utilisateur normal. Le script a process_pathsjuste besoin des chemins.


... -exec sudo -u user process_paths {} \+
Satō Katsura

@SatoKatsura parfois cela échoue avec sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke


2
Si vous voulez que les -execcommandes à appeler comme utilisateur, pourquoi êtes - vous en cours d' exécution à l' findaide sudoen premier lieu?
marcelm

2
@marcelm Je pense que la dernière phrase de la question répond à la vôtre.
Hey

Réponses:


16

Sur les systèmes qui le prennent en charge (GNU et quelques autres), vous pouvez faire:

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

xargsn'est pas exécuté sous sudo, donc il a toujours les uids / gids d'origine et aussi l'environnement d'origine (au sens large), pas celui modifié par sudo.

process_pathsstdin finit cependant par être modifié (selon l' xargsimplémentation, il est ouvert sur /dev/nullou partage le pipefrom sudo/ find.

Pour éviter cela (avec GNU xargset des shells comme ksh, zshou bashqui prennent en charge la substitution de processus), vous pouvez faire:

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

Avec zsh:

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

Dans zsh, en attribuant un nom d'utilisateur à la $USERNAMEvariable spéciale, définissez les uids, gids sur celui de l'utilisateur correspondant dans la base de données utilisateur comme le sudo -u "$SUDO_USER"ferait.

Vous pourriez faire:

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

Mais parce que sudotransmet une $SUDO_COMMANDvariable d'environnement (qui contient la concaténation des arguments avec des espaces) à process_paths, la liste des fichiers finit par être transmise deux fois, process_pathsce qui signifie que la limite de la taille maximale d'args + env est susceptible d'être atteinte s'il y a un grand nombre de fichiers.

Avec la plupart des suimplémentations, vous devriez pouvoir faire:

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

mais comme sun'a pas le même problème.


1

Vous pouvez utiliser sudo:

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

Mais comme dit dans un commentaire, il peut apparemment échouer si le {} est trop long pour sudo.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.