linux - todos - ¿Cómo se encuentra el usuario original a través de múltiples comandos sudo y su?
sudo-i ubuntu (7)
¿Qué le parece usar logname (1) para obtener el nombre de usuario?
Cuando ejecuto un script a través de sudo o su, quiero obtener el usuario original. Esto debería suceder independientemente de múltiples sudo
o su
ejecuciones dentro de cada uno y específicamente sudo su -
.
Alternativa para llamar a ps varias veces: hacer una llamada pstree
pstree -lu -s $$ | grep --max-count=1 -o ''([^)]*)'' | head -n 1
salida (cuando se registra como par): (evan)
pstree argumentos:
- -l: líneas largas (sin acortar)
- -u: muestra cuando el usuario cambia como (nombre de usuario)
- -s $$: muestra a los padres de este proceso
Obtenga el primer cambio de usuario (que es iniciar sesión) con grep -o
y head
.
limitación: el comando no puede contener llaves ()
(normalmente no)
Esta es una función ksh
que escribí en HP-UX. No sé cómo funcionará con Bash
en Linux. La idea es que el proceso sudo
se ejecute como el usuario original y los procesos hijo sean el usuario objetivo. Al retroceder en los procesos principales, podemos encontrar al usuario del proceso original.
#
# 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
}
Sé que la pregunta original era de hace mucho tiempo, pero las personas (como yo) siguen preguntando y este parecía un buen lugar para poner la solución.
Función findUser () del usuario1683793 portada a bash
y extendida, por lo que también devuelve los nombres de usuario almacenados en las bibliotecas 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"
No hay una respuesta perfecta . Cuando cambia las ID de usuario, la ID de usuario original no suele conservarse, por lo que la información se pierde. Algunos programas, como logname
y who -m
implementan un hack donde verifican qué terminal está conectado a stdin
y luego verifican qué usuario está conectado en ese terminal.
Esta solución a menudo funciona, pero no es infalible, y ciertamente no debe considerarse segura. Por ejemplo, imagina si who
saca lo siguiente:
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
usó su
para llegar a la raíz, y ejecuta su programa. Si STDIN
no se redirecciona, entonces un programa como logname
emitirá tom
. Si se redirige (por ejemplo, desde un archivo) como se indica a continuación:
logname < /some/file
Entonces el resultado es " no login name
", ya que la entrada no es el terminal. Más interesante aún, sin embargo, es el hecho de que el usuario podría posar como un usuario diferente conectado. Como Joe inició sesión en pts / 1, Tom podría fingir ser él ejecutándose
logname < /dev/pts1
Ahora, dice joe
, aunque Tom es quien ejecutó el comando. En otras palabras, si usa este mecanismo en cualquier tipo de función de seguridad, está loco.
Resultados:
Usa who am i | awk ''{print $1}''
who am i | awk ''{print $1}''
O nombre de logname
ya que no se garantizan otros métodos.
Iniciado como yo:
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 normal:
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$
retroceder y dar una lista de usuarios
basado en la respuesta del usuario1683793
Al excluir los procesos que no son TTY, omito la raíz como el iniciador del inicio de sesión. No estoy seguro si eso puede exceder demasiado en algún caso
#!/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
o who am i
no me dio la respuesta deseada, especialmente no en listas más largas de su user1
, su user2
, su user3
, ...
Sé que la pregunta original era de hace mucho tiempo, pero las personas (como yo) siguen preguntando y este parecía un buen lugar para poner la solución.