Beim Ausführen eines Skripts über Sudo oder su möchte ich den ursprünglichen Benutzer erhalten. Dies sollte unabhängig von mehreren Sudo
- oder su
-Läufen ineinander und speziell Sudo su -
geschehen.
Ergebnisse:
Verwenden Sie who am i | awk '{print $1}'
OR logname
, da keine anderen Methoden garantiert sind.
Als selbst angemeldet:
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>
Normaler 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$
Es gibt keine perfekte Antwort. Wenn Sie Benutzer-IDs ändern, wird die ursprüngliche Benutzer-ID normalerweise nicht beibehalten, sodass die Informationen verloren gehen. Einige Programme wie logname
und who -m
implementieren einen Hack, in dem sie prüfen, welches Terminal mit stdin
verbunden ist. Anschließend wird überprüft, welcher Benutzer an diesem Terminal angemeldet ist.
Diese Lösung oft funktioniert, ist jedoch nicht narrensicher und sollte sicherlich nicht als sicher angesehen werden. Stellen Sie sich beispielsweise vor, dass who
Folgendes ausgibt:
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
verwendete su
, um zum Root zu gelangen, und führt Ihr Programm aus. Wenn STDIN
nicht umgeleitet wird, gibt ein Programm wie logname
tom
aus. Wenn es IS umgeleitet wird (z. B. von einer Datei):
logname < /some/file
Dann lautet das Ergebnis "no login name
", da die Eingabe nicht das Terminal ist. Noch interessanter ist jedoch die Tatsache, dass der Benutzer sich als anderer angemeldeter Benutzer ausgeben könnte. Da Joe auf pts/1 eingeloggt ist, könnte Tom so tun, als wäre er er, indem er rannte
logname < /dev/pts1
Nun heißt es joe
, obwohl tom derjenige ist, der den Befehl ausgeführt hat. Mit anderen Worten, wenn Sie diesen Mechanismus in irgendeiner Sicherheitsrolle verwenden, sind Sie verrückt.
Dies ist eine ksh
-Funktion, die ich unter HP-UX geschrieben habe. Ich weiß nicht, wie es mit Bash
unter Linux funktioniert. Die Idee ist, dass der Prozess Sudo
als ursprünglicher Benutzer ausgeführt wird und die untergeordneten Prozesse der Zielbenutzer sind. Durch das Zurückkehren durch übergeordnete Prozesse können wir den Benutzer des ursprünglichen Prozesses finden.
#
# 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
}
Ich weiß, dass die ursprüngliche Frage schon lange her war, aber die Leute (wie ich) fragen immer noch und dies sah nach einem guten Ort aus, um die Lösung zu finden.
Wie wäre es mit logname (1), um den Anmeldenamen des Benutzers zu erhalten?
die Funktion findUser () von user1683793 wurde in bash
portiert und erweitert, sodass auch in NSS-Bibliotheken gespeicherte Benutzernamen zurückgegeben werden.
#!/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"
zurückfahren und eine Liste der Benutzer angeben
basierend auf der Antwort von user1683793
Durch das Auslassen von Nicht-TTY-Prozessen überspringe ich root als Initiator der Anmeldung. Ich bin mir nicht sicher, ob das in manchen Fällen zuviel ist
#!/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
oder who am i
gab mir nicht die gewünschte Antwort, vor allem nicht in längeren Listen von su user1
, su user2
, su user3
, ...
Ich weiß, dass die ursprüngliche Frage schon lange her war, aber die Leute (wie ich) fragen immer noch und dies sah nach einem guten Ort aus, um die Lösung zu finden.
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
Das ist das einzige, was für mich funktioniert hat.
Alternative zum mehrfachen Anrufen von ps: Führen Sie einen Pstree-Anruf aus
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
ausgabe (wenn als gerade angemeldet): (evan)
pstree Argumente:
Holen Sie sich die erste Benutzeränderung (Login) mit grep -o
und head
.
einschränkung: Der Befehl darf keine geschweiften Klammern enthalten ()
(normalerweise nicht)