programing tip

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

itbloger 2020. 10. 12. 07:17
반응형

여러 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의 답변에 따라

By exlcuding non-TTY processes, I skip root as the initiator of the login. I'm not sure if that may exlcude too much in some case

#!/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 or who am i didn't give me the desired answer, especially not in longer lists of su user1, su user2, su user3, ...

I know the original question was from a long time ago but people (such as me) are still asking and this looked like a good place to put the solution.


Alternative to calling ps multiple times: do one pstree call

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

output (when logged in as even): (evan)

pstree arguments:

  • -l: long lines (not shortening)
  • -u: show when user changes as (userName)
  • -s $$: show parents of this process

Get the first user change (which is login) with grep -o and head.

limitation:the command may not contain any braces () (it does not normally)

참고URL : https://stackoverflow.com/questions/4598001/how-do-you-find-the-original-user-through-multiple-sudo-and-su-commands

반응형