Как найти исходного пользователя с помощью нескольких команд sudo и su?
при запуске скрипта через sudo или su я хочу получить оригинальный пользователь. Это должно произойти независимо от нескольких sudo
или su
работает внутри друг друга и особенно sudo su -
.
8 ответов:
результаты:
использовать
who am i | awk '{print }'
илиlogname
как никакие другие методы не гарантировано.вошел в систему как self:
evan> echo $USER evan evan> echo $SUDO_USER evan> echo $LOGNAME evan evan> whoami evan evan> who am i | awk '{print }' evan evan> logname evan evan>
нормальный судо:
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 }' 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 }' 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 }' evan tom$ logname evan tom$
нет идеальный ответ. При изменении идентификаторов пользователей, исходный идентификатор пользователя обычно не сохраняется, поэтому информация теряется. Некоторые программы, такие как
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)
tom
используетсяsu
чтобы добраться до root, и запускает вашу программу. ЕслиSTDIN
не перенаправляется, то программа, какlogname
выводитtom
. Если он перенаправляется (например, из файла) так:logname < /some/file
результат "
no login name
", так как вход не является терминалом. Еще более интересным, однако, является тот факт, что пользователь может представлять собой другого зарегистрированного пользователя. Поскольку Джо вошел в систему на 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 }
Я знаю, что первоначальный вопрос был давно, но люди (такие как я) все еще спрашивают, и это выглядело как хорошее место для размещения решение.
функция findUser () пользователя 1683793 перенесена в
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"
велоспорт назад и предоставление списка пользователей
на основе ответа пользователя 1683793
путем исключения не-TTY процессов, я пропускаю root в качестве инициатора входа в систему. Я не уверен, что это может быть слишком много в некоторых случаях
#!/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
,...
Я знаю, что первоначальный вопрос был издавна, но люди (такие как я) все еще спрашивают, и это выглядело как хорошее место, чтобы положить решение.
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
это единственное, что работал для меня.
альтернатива вызову ps несколько раз: сделайте один вызов pstree
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
выход (при входе в систему как даже):
(evan)
pstree аргументы:
- - l: длинные линии (не сокращая)
- - u: показать, когда пользователь изменяет как (имя пользователя)
- - s $$: показать родителям этого процесса
получить первое изменение пользователя (который является логин) с
grep -o
иhead
.ограничение: команда не может содержат любые фигурные скобки
()
(обычно это не так)