Как найти оригинального пользователя через несколько команд Sudo и SU?
Вопрос
При запуске скрипта через Sudo или SU я хочу получить исходного пользователя. Это должно произойти независимо от нескольких sudo
или же su
бегает внутри друг друга и конкретно sudo su -
.
Решение
Полученные результаты:
Использовать who am i | awk '{print $1}'
ИЛИ ЖЕ logname
Поскольку никакие другие методы не гарантированы.
Вошел в систему как Self:
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 -; Су Том:
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$
Другие советы
Нет никаких идеально отвечать. При изменении идентификатора пользователей исходный идентификатор пользователя обычно не сохраняется, поэтому информация теряется. Некоторые программы, такие как 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
}
Я знаю, что первоначальный вопрос давным -давно был, но люди (такие как я) все еще задают, и это выглядело как хорошее место для постановки решения.
Как насчет использования logname (1) для получения имени входа пользователя?
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
Это единственное, что сработало для меня.
Функция FinduSer () user1683793 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
, ...
Я знаю, что первоначальный вопрос давным -давно был, но люди (такие как я) все еще задают, и это выглядело как хорошее место для постановки решения.
Альтернатива вызову PS несколько раз: сделайте один вызов Pstree
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
вывод (при входе в систему как даже): (evan)
Аргументы Pstree:
- -l: длинные линии (не сокращение)
- -У: покажите, когда пользователь меняется как (имя пользователя)
- -s $$: покажите родителям этого процесса
Получите первое изменение пользователя (которое является входом в систему) с grep -o
а также head
.
Ограничение: команда может не содержать брекеты ()
(Обычно это не)