99 votes

Comment retrouver l'utilisateur d'origine à travers plusieurs commandes sudo et su ?

Lorsque vous exécutez un script via sudo ou su, je veux récupérer l'utilisateur d'origine. Cela devrait se produire indépendamment des multiples sudo ou su s'entrecroisent et spécifiquement sudo su - .

143voto

evan Points 4825

Résultats :

Utilice who am i | awk '{print $1}' OU logname car aucune autre méthode n'est garantie.

Connecté en tant que self :

evan> echo $USER
evan
evan> echo $SUDO_USER

evan> echo $LOGNAME
evan
evan> whoami
evan
evan> who am i | awk '{print $1}'
evan
evan> logname
evan
evan>

Normal sudo :

evan> sudo -s
root> echo $USER
root
root> echo $SUDO_USER
evan
root> echo $LOGNAME
root
root> whoami
root
root> who am i | awk '{print $1}'
evan
root> logname
evan
root>

sudo su - :

evan> sudo su -
[root ]# echo $USER
root
[root ]# echo $SUDO_USER

[root ]# echo $LOGNAME
root
[root ]# whoami
root
[root ]# who am i | awk '{print $1}'
evan
[root ]# logname
evan
[root ]#

sudo su - ; su tom :

evan> sudo su -
[root ]# su tom
tom$ echo $USER
tom
tom$ echo $SUDO_USER

tom$ echo $LOGNAME
tom
tom$ whoami
tom
tom$ who am i | awk '{print $1}'
evan
tom$ logname
evan
tom$

1 votes

Dans ce cas, vous pouvez simplement utiliser who | awk '{print $1}'

2 votes

... si vous êtes le seul à être connecté (et ce n'est qu'une fois).

9 votes

Il suffit de deux arguments : who am i est la même chose que who smells bad . En outre, cela ne fonctionne que si STDIN est associé à un ATS. Ainsi, si vous exécutez echo "hello" | who am i cela ne fonctionnera tout simplement pas.

19voto

tylerl Points 14541

Il n'y a pas parfait réponse. Lorsque vous changez d'identifiant, l'identifiant d'origine n'est généralement pas conservé, et l'information est donc perdue. Certains programmes, tels que logname y who -m mettre en place un hack où ils vérifient quel terminal est connecté à stdin et vérifiez ensuite quel utilisateur est connecté sur ce terminal.

Cette solution souvent fonctionne, mais n'est pas infaillible, et ne doit certainement pas être considéré comme sûr. Par exemple, imaginez que who produit les résultats suivants :

tom     pts/0        2011-07-03 19:18 (1.2.3.4)
joe     pts/1        2011-07-03 19:10 (5.6.7.8)

tom utilisé su pour arriver à Root, et exécute votre programme. Si STDIN n'est pas redirigé, alors un programme comme logname produira tom . S'il EST redirigé (par exemple à partir d'un fichier) comme tel :

logname < /some/file

Alors le résultat est " no login name "puisque l'entrée n'est pas le terminal. Mais ce qui est encore plus intéressant, c'est que l'utilisateur peut se faire passer pour un autre utilisateur connecté. Puisque Joe est connecté sur pts/1, Tom pourrait se faire passer pour lui en exécutant

logname < /dev/pts1

Maintenant, il est dit joe même si Tom est celui qui a lancé la commande. En d'autres termes, si vous utilisez ce mécanisme dans un quelconque rôle de sécurité, vous êtes fou.

2 votes

Si vous exécutez vous-même le script (comme en témoignent les commandes utilisées), la sécurité n'est pas le problème. Si c'est le cas, vous avez beaucoup plus de problème puisqu'ils ont également un accès sudo. La personne pourrait simplement copier le script et le modifier comme bon lui semble. C'est simplement un moyen d'obtenir le nom de connexion pour l'utiliser dans un script. Ou est-ce que j'ai raté quelque chose dans ce que vous dites ?

1 votes

@evan : Avoir un accès sudo n'implique pas la possibilité d'écraser des fichiers.

0 votes

@Flimzy Dans quel cas Root n'a pas la possibilité d'écraser un fichier ?

8voto

user1683793 Points 51

Il s'agit d'un ksh que j'ai écrite sur HP-UX. Je ne sais pas comment elle fonctionnera avec Bash dans Linux. L'idée est que le sudo s'exécute en tant qu'utilisateur d'origine et les processus enfants sont l'utilisateur cible. En remontant dans les processus parents, nous pouvons trouver l'utilisateur du processus d'origine.

#
# The options of ps require UNIX_STD=2003.  I am setting it
# in a subshell to avoid having it pollute the parent's namespace.
#
function findUser
{
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser
    while [ "$thisUser" = "$origUser" ]
    do
        ( export UNIX_STD=2003; ps -p$thisPID -ouser,ppid,pid,comm ) | grep $thisPID | read thisUser myPPid myPid myComm
        thisPID=$myPPid
    done
    if [ "$thisUser" = "root" ]
    then
        thisUser=$origUser
    fi
    if [ "$#" -gt "0" ]
    then
        echo $origUser--$thisUser--$myComm
    else
        echo $thisUser
    fi
    return 0
}

Je sais que la question originale date d'il y a longtemps, mais les gens (comme moi) se posent toujours la question et cela semblait être un bon endroit pour mettre la solution.

6voto

sam Points 21

Pourquoi ne pas utiliser logname(1) pour obtenir le nom de connexion de l'utilisateur ?

0 votes

logname(1) ne fonctionne pas mais logname fait - en ajoutant les résultats ci-dessus

0 votes

À l'origine, j'avais essayé $LOGNAME mais ça n'a pas marché. Également ajouté aux résultats ci-dessus.

0 votes

Fait logname nécessite toujours un tty ? Avec mes tests, il passe toujours. (Peut-être que j'ai fait quelque chose de mal.) Je suis sous linux avec coreutils 8.26.

2voto

asdfghjkl Points 11

La fonction findUser() de l'utilisateur1683793 est portée à bash et étendu de sorte qu'il renvoie également les noms d'utilisateur stockés dans les bibliothèques NSS.

#!/bin/bash

function findUser() {
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser

    while [ "$thisUser" = "$origUser" ]
    do
        ARR=($(ps h -p$thisPID -ouser,ppid;))
        thisUser="${ARR[0]}"
        myPPid="${ARR[1]}"
        thisPID=$myPPid
    done

    getent passwd "$thisUser" | cut -d: -f1
}

user=$(findUser)
echo "logged in: $user"

0 votes

Pour info : cette fonction (et celle sur laquelle elle est basée) ne permet pas de revenir en arrière dans les multiples shells créés par sudo et imbriqués les uns dans les autres.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X