it-swarm.com.de

Wie finden Sie den ursprünglichen Benutzer durch mehrere Sudo- und Su-Befehle?

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.

75
evan

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$
119
evan

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 lognametom 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.

11
tylerl

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.

8
user1683793

Wie wäre es mit logname (1), um den Anmeldenamen des Benutzers zu erhalten?

5
sam

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"
2
asdfghjkl

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.

2
ULick
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.

1

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:

  • -l: lange Zeilen (nicht kürzen)
  • -u: anzeigen, wenn sich der Benutzer ändert als (Benutzername)
  • -s $$: Eltern dieses Prozesses anzeigen

Holen Sie sich die erste Benutzeränderung (Login) mit grep -o und head.

einschränkung: Der Befehl darf keine geschweiften Klammern enthalten () (normalerweise nicht)

0
simohe