Pregunta

Cuando se ejecuta una secuencia de comandos a través de sudo o su quiero llegar al usuario original. Esto debería ocurrir sin importar múltiples sudo o su se ejecuta dentro de la otra y específicamente sudo su -.

¿Fue útil?

Solución

Resultados:

Uso who am i | awk '{print $1}' O logname como están garantizados no hay otros métodos.

Conectado como uno mismo:

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 -; Do 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$

Otros consejos

No hay perfecta respuesta. Cuando cambia los ID de usuario, el ID de usuario original no se conserva por lo general, por lo que la información se pierde. Algunos programas, como logname y who -m implementar un truco en el que comprobar para ver qué terminal está conectado a stdin, y después comprobar para ver lo que el usuario ha iniciado la sesión en ese terminal.

Esta solución a menudo las obras, pero no es infalible, y ciertamente no debe considerarse seguro. Por ejemplo, imaginar si who da salida a la 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 utiliza su para llegar a la raíz, y se ejecuta el programa. Si STDIN no se redirige, a continuación, un programa como logname salida tom voluntad. Si es redirigido (por ejemplo de un archivo) como así:

logname < /some/file

A continuación, 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 hacerse pasar por un diferente usuario conectado. Desde que Joe se registra en el pts / 1, Tom podría hacerse pasar por él mediante la ejecución

logname < /dev/pts1

Ahora, dice joe a pesar de que Tom es el que ejecutó el comando. En otras palabras, si se utiliza este mecanismo en cualquier tipo de papel de seguridad, que estás loco.

Esta es una función ksh escribí en HP-UX. No sé cómo va a funcionar con Bash en Linux. La idea es que el proceso sudo se ejecuta como el usuario original y los procesos secundarios son el usuario de destino. Por ciclismo vuelta a través de procesos padre, se encuentra el 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 desde hace mucho tiempo, pero la gente (como yo) todavía están pidiendo y esto parecía un lugar bueno para poner la solución.

¿Y si uso logname (1) para obtener el nombre de inicio de sesión del usuario?

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

Eso es lo único que trabajó para mí.

función

findUser de user1683793 () portado a bash y se extendió de modo que devuelve los nombres de usuario almacenados en las bibliotecas NSS también.

#!/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"

Ciclo atrás y dar una lista de usuarios

basado en la respuesta de user1683793

Por exlcuding procesos no TTY, I omitir raíz como el iniciador de la sesión. No estoy seguro de si eso puede exlcude demasiado en algunos casos

#!/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 desde hace mucho tiempo, pero la gente (como yo) todavía están pidiendo y esto parecía un lugar bueno para poner la solución.

Alternativa a llamar varias veces ps: hacer una llamada pstree

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

salida (cuando se haya identificado como par): (evan)

pstree argumentos:

  • -l: líneas largas (no acortamiento)
  • -u: mostrar cuando los cambios de usuario como (nombre de usuario)
  • -s $$: mostrar a los padres de este proceso

Obtener el primer cambio de usuario (que es login) con grep -o y head.

limitación: el comando no puede contener cualquier () tirantes (no normalmente)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top