[linux] 여러 sudo 및 su 명령을 통해 원래 사용자를 어떻게 찾습니까?

sudo 또는 su를 통해 스크립트를 실행할 때 원래 사용자를 얻고 싶습니다. 이것은 여러 개 sudo또는 su서로 내부에서 특히 실행에 관계없이 발생해야합니다 sudo su -.



답변

결과 :

다른 방법은 보장되지 않으므로 who am i | awk '{print $1}'OR logname을 사용하십시오 .

본인으로 로그인 :

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>

일반 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$


답변

완벽한 답 은 없습니다 . 사용자 ID를 변경할 때 원래 사용자 ID는 일반적으로 보존되지 않으므로 정보가 손실됩니다. 같은 일부 프로그램, logname그리고 who -m그들이 연결되는 터미널 확인 해킹 구현 stdin한 다음 해당 터미널에 로그인 한 어떤 사용자 확인을.

이 솔루션은 종종 작동하지만 완벽하지는 않으며 확실히 안전한 것으로 간주해서는 안됩니다. 예를 들어 who다음을 출력 한다고 상상해보십시오 .

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

tomsu루트에 도달하고 프로그램을 실행하는 데 사용 됩니다. 경우 STDIN처럼, 다음 프로그램 리디렉션되지 logname가 출력 tom. 다음과 같이 리디렉션되는 경우 (예 : 파일에서) :

logname < /some/file

no login name입력이 터미널이 아니기 때문에 결과는 ” “입니다. 하지만 더 흥미로운 것은 사용자가 다른 로그인 사용자로 위장 할 수 있다는 사실입니다. Joe가 pts / 1에 로그인했기 때문에 Tom은 다음을 실행하여 자신을 가장 할 수 있습니다.

logname < /dev/pts1

이제 joe명령을 실행 한 사람은 톰이라고합니다. 즉, 어떤 종류의 보안 역할에서든이 메커니즘을 사용하면 미친 짓입니다.


답변

이것은 ksh내가 HP-UX에서 작성한 함수입니다. BashLinux에서 어떻게 작동할지 모르겠습니다 . 아이디어는 sudo프로세스가 원래 사용자로 실행되고 하위 프로세스가 대상 사용자라는 것입니다. 상위 프로세스를 순환하여 원래 프로세스의 사용자를 찾을 수 있습니다.

#
# 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
}

나는 원래 질문이 오래 전의 질문이라는 것을 알고 있지만 (나와 같은) 사람들이 여전히 묻고 있으며 이것은 해결책을 제시하기에 좋은 장소처럼 보였습니다.


답변

사용자의 로그인 이름을 얻기 위해 logname (1)을 사용하는 것은 어떻습니까?


답변

THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`

그것이 나를 위해 일한 유일한 것입니다.


답변

user1683793의 findUser () 함수가 포팅 bash되고 확장되어 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"


답변

다시 순환하고 사용자 목록 제공

user1683793의 답변에 따라

비 TTY 프로세스를 제외하여 로그인 시작 자로서 루트를 건너 뜁니다. 어떤 경우에는 너무 많이 빠져 나갈 수 있는지 잘 모르겠습니다

#!/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또는 who am i, 특히하지의 이상 목록에 나에게 원하는 대답을하지 않았다 su user1, su user2, su user3,...

나는 원래 질문이 오래 전의 질문이라는 것을 알고 있지만 (나와 같은) 사람들이 여전히 묻고 있으며 이것은 해결책을 제시하기에 좋은 장소처럼 보였습니다.