sudo comme un autre utilisateur avec son environnement

56

$ whoami
admin
$ sudo -S -u otheruser whoami
otheruser
$ sudo -S -u otheruser /bin/bash -l -c 'echo $HOME'
/home/admin

Pourquoi n'est-il pas $HOMEconfiguré /home/otherusermême si bash est appelé en tant que shell de connexion?

Plus précisément, /home/otheruser/.bashrcne pas être source. En outre, /home/otheruser/.profilene pas être source. - ( /home/otheruser/.bash_profilen'existe pas)

utilisateur80551
la source
Une solution à cette question résoudra également l’autre question. Vous voudrez peut-être supprimer l’autre question dans cette situation.
Pavel Šimerda

Réponses:

83

Pour invoquer un shell de connexion en utilisant sudosimplement utiliser -i. Lorsque la commande n'est pas spécifiée, vous obtenez une invite du shell de connexion, sinon vous obtenez le résultat de votre commande.

Exemple (shell de connexion):

sudo -i

Exemple (avec un utilisateur spécifié):

sudo -i -u user

Exemple (avec une commande):

sudo -i -u user whoami

Exemple (utilisateur d'impression $HOME):

sudo -i -u user echo \$HOME

Remarque: le caractère barre oblique inverse garantit que le signe dollar atteint le shell de l'utilisateur cible et n'est pas interprété dans le shell de l'utilisateur appelant.

Je viens de vérifier le dernier exemple avec strace qui vous dit exactement ce qui se passe. Le résultat ci-dessous montre que le shell est appelé avec --loginet avec la commande spécifiée, exactement comme dans votre appel explicite à bash, mais en plus, sudo peut effectuer son propre travail comme définir le fichier $HOME.

# strace -f -e process sudo -S -i -u user echo \$HOME
execve("/usr/bin/sudo", ["sudo", "-S", "-i", "-u", "user", "echo", "$HOME"], [/* 42 vars */]) = 0
...
[pid 12270] execve("/bin/bash", ["-bash", "--login", "-c", "echo \\$HOME"], [/* 16 vars */]) = 0
...

J'ai remarqué que vous utilisez -Set je ne pense pas que ce soit généralement une bonne technique. Si vous souhaitez exécuter des commandes en tant qu'utilisateur différent sans effectuer d'authentification à l'aide du clavier, vous pouvez utiliser plutôt SSH. Il fonctionne pour localhostainsi que pour d'autres hôtes et fournit une authentification par clé publique qui fonctionne sans aucune entrée interactive.

ssh user@localhost echo \$HOME

Remarque: vous n'avez besoin d'aucune option spéciale avec SSH car le serveur SSH crée toujours un shell de connexion accessible au client SSH.

Pavel imeri
la source
2
sudo -i -u user echo \$HOMEça ne marche pas pour moi. Sortie: $HOME. strace donne le même résultat que le vôtre. Quel est le problème?
John_West
Aucune idée, ça marche toujours pour moi, il faudrait que je le voie ou même que je touche au système.
Pavel Šimerda
10

Tu donnes trop de crédit à Bash. Tous les "shell de connexion" signifient que Bash indique quels fichiers sont générés au démarrage et à l’arrêt. La $HOMEvariable n'y figure pas.

La documentation Bash explique plus en détail ce que le shell de connexion signifie: https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Bash-Startup-Files

En fait, Bash ne fait rien du $HOMEtout. $HOMEest défini par tout ce qui appelle le shell (login, ssh, etc.), et le shell en hérite. Peu importe ce qui a commencé votre shell en tant qu'admin set $HOME, puis exec-ed bash, de sudopar sa conception, il ne modifie pas l'environnement à moins d'y être invité ou configuré, de sorte bashqu'un autre utilisateur l'a hérité de votre shell.

Si vous souhaitez sudogérer davantage l'environnement que prévu, consultez le -icommutateur sudo. Essayer:

sudo -S -u otheruser -i /bin/bash -l -c 'echo $HOME'

La page de manuel de sudo le décrit plus en détail, mais pas très bien, je pense: http://linux.die.net/man/8/sudo

Jeff Snider
la source
4
$ HOME n'est pas défini par bash - Merci, je ne le savais pas.
user80551
Cherchez strace dans ma réponse. Cela montre que vous n'avez pas besoin de créer une /bin/bash -l -c 'echo $HOME'ligne de commande vous-même lorsque vous l'utilisez -i.
Pavel Šimerda le
1
Cette sudosyntaxe a jeté une erreur sur ma machine. ( suutilise l' -coption, mais je ne le pense pas sudo.) J'ai eu plus de chance avec:HomeDir=$( sudo -u "$1" -H -s echo "\$HOME" )
palswim
Oui, @ Palswim a raison. Pas sûr de -S(je n'en ai pas eu besoin, alors je l'ai laissé), mais -cça ne marche pas ici, il faut à la -splace.
polynomial_donut