Eu assumo que a conta raiz não está habilitada (como é por padrão), então somente sudo -i é aplicável para um usuário se tornar root . Minha sugestão é o seguinte script que usa os comandos who -u e pgrep -at <tty parsed from who -u> para descobrir qual user na qual tty executou o comando sudo -i .
#!/bin/bash
LANG=C who -u | while read -a line; do # Output the whole line: echo "${line[@]}"
IS_ROOT="$(pgrep -at "${line[1]}" | grep 'sudo -i')"
[[ ! -z "${IS_ROOT}" ]] && printf '%-7s ( PID %-6s at %s on TTY %-7s) is ROOT: %s %s\n' "${line[0]}" "${line[5]}" "${line[4]}" "${line[1]}" "$IS_ROOT"
done | sed '/grep sudo -i/d' | sort -k13 -k6
Explicação:
-
who -umostra os usuários conectados com os PIDs de suas sessões. ProvavelmenteLANG=Cnão é obrigatório - ele é colocado para garantir formato de data / hora idêntico em máquinas com diferentes configurações delocale. -
O loop
whileirádodos comandos enquanto houver fluxo no stdin . -
O comando
read -alerá o fluxo de entrada linha por linha e atribuirá essas linhas como uma matriz à "variável"$line. Nós poderíamos produzir toda a linha por um comando como:echo "${line[@]}". Portanto,${line[1]}significa a segunda variável da matriz$line(a primeira é0). No caso atual,${line[1]}é o TTY da saída dewho -u. -
Aqui está um script simples que gerará uma "tabela" com as relações entre os elementos da matriz e seus valores:
line=( $(LANG=C who -u | head -1) ); for i in {0..6}; do printf '%-11s' "${line[$i]}"; done; echo; for i in {0..6}; do printf '${line[%s]} ' "$i"; done; echo guest tty7 2018-01-03 09:52 old 1847 (:0) ${line[0]} ${line[1]} ${line[2]} ${line[3]} ${line[4]} ${line[5]} ${line[6]} -
A saída do comando
pgrep -at "${line[1]}" | grep 'sudo -i'será assinada como valor$()para a variável$IS_ROOT. -
O comando
pgrep -at "TTY"produzirá os PIDs de todos os processos em determinados TTY - opção-t--terminal, e a opção-a--list-namelistará os nomes de PIDs e processos. -
A expressão
[[ ! -z "${IS_ROOT}" ]] &&pode ser lida desta forma: se[a variável"${IS_ROOT}"não for!vazio-z, então&&ou senão||. -
O comando
printfé usado para formatar a saída ( referência ):printf '%s some text %s' "$var1" "$var2" -
Finalmente,
sed '/grep sudo -i/d'excluirá a linha não assistida (que contém nosso comandogrep 'sudo -i') da saída dewhileesort -k13 -k6classificará a saída pelas colunas 13 e 6.
Chame o script find-root , torne-o executável ( chmod +x find-root ) e execute-o.
Aqui está uma saída simples:
$ ./find-root
spas ( PID 14035 at 12:54 on TTY pts/20 ) is ROOT: 23518 sudo -i
spas ( PID 14035 at 12:36 on TTY pts/4 ) is ROOT: 23589 sudo -i
guest ( PID 23575 at 15:00 on TTY pts/4 ) is ROOT: 23589 sudo -i
guest ( PID 24321 at 15:30 on TTY tty1 ) is ROOT: 24386 sudo -i
Aqui está uma demonstração (em uma sessão mutt ) de como o script funciona ( em sua versão anterior ):
Coloque o script em /usr/local/bin para disponibilizá-lo como comando shell. Para fazer isso, copie e execute as seguintes linhas como um único comando:
cat << EOF | sudo tee /usr/local/bin/find-root && sudo chmod +x /usr/local/bin/find-root
#!/bin/bash
LANG=C who -u | while read -a line; do
IS_ROOT="$(pgrep -at "${line[1]}" | grep 'sudo -i')"
[[ ! -z "${IS_ROOT}" ]] && printf '%-7s ( PID %-6s at %s on TTY %-7s) is ROOT: %s %s\n' "${line[0]}" "${line[5]}" "${line[4]}" "${line[1]}" "$IS_ROOT"
done | sed '/grep sudo -i/d' | sort -k13 -k6
EOF
Explicação:
-
O comando
cat << EOFproduzirá as próximas linhas, a menos que a stringEOFseja encontrada. Observe as barras invertidas$que irão escapar do caractere especial$e serão produzidas literalmente dentro de cat. -
Esta saída será canalizada
|para o stdin do comandotee(executado porsudo) que gravará o arquivo/usr/local/bin/find-root. -
Se o comando anterior for bem-sucedido
&&, o comandosuddo chmod +xserá executado.
Veja também: