複数のsudoとsuコマンドを使用して、元のユーザーをどのように見つけますか?

StackOverflow https://stackoverflow.com/questions/4598001

  •  15-10-2019
  •  | 
  •  

質問

SudoまたはSUを介してスクリプトを実行するときは、元のユーザーを取得したいと思います。これは、複数に関係なく発生するはずです sudo また su 互いに、特に内部で走ります sudo su -.

役に立ちましたか?

解決

結果:

使用する who am i | awk '{print $1}' また 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は通常保存されていないため、情報が失われます。などの一部のプログラム lognamewho -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)

tom 使用済み su ルートに到達し、プログラムを実行します。もしも STDIN リダイレクトされておらず、次にプログラム logname 出力されます tom. 。そうであるように(ファイルから)リダイレクトされている場合:

logname < /some/file

その後、結果は "no login name「、入力は端末ではないので、さらに興味深いことに、ユーザーがユーザーのログインとしてポーズをとることができるという事実です。JoeはPTS/1にログインしているため、トムは実行して彼のふりをすることができます。

logname < /dev/pts1

今、それは言います joe トムはコマンドを実行した人ですが。言い換えれば、このメカニズムをあらゆる種類のセキュリティの役割で使用する場合、あなたは狂っています。

これは ksh hp-uxで書いた関数。それがどのように機能するのかわかりません Bash Linuxで。アイデアはそれです 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以外のプロセスをexlCudingすることにより、ログインのイニシエーターとしてルートをスキップします。ある場合にそれがあまりにも多くのことをするかもしれないかどうかはわかりません

#!/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, ...

私は元の質問が昔からだったことを知っていますが、人々(私のような)はまだ尋ねており、これは解決策を置くのに良い場所のように見えました。

PSを複数回呼び出す代わりに:1つのPSTREE呼び出しを行う

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

出力(均一にログインしたとき): (evan)

PSTREEの議論:

  • -L:長い線(短縮されない)
  • -u:ユーザーが(ユーザー名)として変更されたときに表示します
  • -s $$:このプロセスの親に見せます

最初のユーザーの変更(ログイン)を取得します grep -ohead.

制限:コマンドにはブレースが含まれていない場合があります () (通常はありません)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top