Comment trouvez-vous l'utilisateur d'origine par plusieurs commandes sudo et su?
Question
Lors de l'exécution d'un script via sudo ou su que je veux obtenir l'utilisateur d'origine. Cela devrait se faire indépendamment de multiples pistes de sudo
ou su
à l'intérieur de l'autre et plus particulièrement sudo su -
.
La solution
Résultats:
Utilisez who am i | awk '{print $1}'
OU logname
comme aucune autre méthode sont garantis.
Connecté en tant que auto:
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$
Autres conseils
Il n'y a pas de parfait réponse. Lorsque vous modifiez les ID utilisateur, l'ID utilisateur d'origine est généralement pas préservée, afin que l'information est perdue. Certains programmes, tels que logname
et who -m
mettre en œuvre un hack où ils vérifient pour voir quelle borne est reliée à stdin
, puis vérifier pour voir ce que l'utilisateur est connecté sur ce terminal.
Cette solution souvent fonctionne, mais il est pas à toute épreuve, et ne devrait certainement pas être considérée comme sûre. Par exemple, imaginez si who
produit les éléments 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 se rendre à la racine, et exécute votre programme. Si STDIN
n'est pas redirigé, un programme comme logname
volonté tom
de sortie. Si elle est redirigée (par exemple à partir d'un fichier) comme ceci:
logname < /some/file
Ensuite, le résultat est « no login name
», puisque l'entrée est pas le terminal. Plus intéressant encore, cependant, est le fait que l'utilisateur pourrait se présenter comme un autre utilisateur connecté. Depuis Joe est connecté sur pts / 1, Tom pouvait prétendre être lui en exécutant
logname < /dev/pts1
Maintenant, il dit joe
même si Tom est celui qui a couru la commande. En d'autres termes, si vous utilisez ce mécanisme dans toute sorte de rôle de sécurité, vous êtes fou.
Ceci est une fonction ksh
je l'ai écrit sur HP-UX. Je ne sais pas comment cela fonctionnera avec Bash
sous Linux. L'idée est que le processus de sudo
est en cours d'exécution en tant qu'utilisateur d'origine et les processus enfants sont l'utilisateur cible. En vélo à travers les processus parents, nous pouvons trouver l'utilisateur du processus original.
#
# 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 initiale était d'il y a longtemps, mais les gens (comme moi) demandent encore et cela ressemblait à un bon endroit pour mettre la solution.
Comment l'utilisation logname (1) pour obtenir le nom de connexion de l'utilisateur?
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
C'est la seule chose qui a fonctionné pour moi.
fonction pour user1683793 findUser () et porté à bash
étendu il retourne les noms d'utilisateur stockés dans les bibliothèques NSS ainsi.
#!/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"
faire du vélo en arrière et donner une liste d'utilisateurs
basé sur la réponse de user1683793
Par exlcuding processus non ATS, je sauter racine que l'initiateur de la connexion. Je ne sais pas si cela peut exlcude trop dans certains cas,
#!/bin/ksh
function findUserList
{
typeset userList prevUser thisPID thisUser myPPid myPid myTTY myComm
thisPID=$$ # starting with this process-ID
while [ "$thisPID" != 1 ] # and cycling back to the origin
do
( ps -p$thisPID -ouser,ppid,pid,tty,comm ) | grep $thisPID | read thisUser myPPid myPid myTTY myComm
thisPID=$myPPid
[[ $myComm =~ ^su ]] && continue # su is always run by root -> skip it
[[ $myTTY == '?' ]] && continue # skip what is running somewhere in the background (without a terminal)
if [[ $prevUser != $thisUser ]]; then # we only want the change of user
prevUser="$thisUser" # keep the user for comparing
userList="${userList:+$userList }$thisUser" # and add the new user to the list
fi
#print "$thisPID=$thisUser: $userList -> $thisUser -> $myComm " >&2
done
print "$userList"
return 0
}
logname
ou who am i
ne m'a pas donné la réponse désirée, surtout pas dans les listes de plus su user1
, su user2
, su user3
, ...
Je sais que la question initiale était d'il y a longtemps, mais les gens (comme moi) demandent encore et cela ressemblait à un bon endroit pour mettre la solution.
Alternative à appeler ps plusieurs fois: faire un appel pstree
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
sortie (lorsque connecté en tant que pair): (evan)
arguments pstree:
- -l: les longues lignes (pas raccourcissant)
- -u: show lors du changement de l'utilisateur que (userName)
- -s $$: les parents montrent de ce processus
Obtenir le premier changement d'utilisateur (qui est connexion) avec grep -o
et head
.
limitation: la commande peut ne pas contenir d'accolades ()
(il n'a pas normalement)