Com base no uso do @ roaiama do comando join
, essa resposta usa getent
para obter os arquivos passwd e shadow em vez de lê-los diretamente e, em seguida, usa chpasswd
no host remoto para alterar as senhas. / p>
O código de alteração de senha é mais simples por causa de chpasswd
, mas fazer uma cópia de backup das entradas de sombra antigas é um pouco mais complicado porque estamos usando getent shadow
no host remoto também.
join -t : -j 1 -o 2.{1..2} \
<(getent passwd | awk -F: '$3 > 1000 {print $1}' | sort) \
<(getent shadow | sort) |
ssh remotehost 'umask 0027 &&
getent shadow > /etc/shadow.old &&
chgrp shadow /etc/shadow.old &&
chpasswd -e 2>/dev/null'
Ele canaliza apenas os dois primeiros campos, o nome de usuário e a senha criptografada (o formato de saída é um par "username: password" por linha), em ssh. Depois de fazer uma cópia de backup do arquivo shadow antigo, o shell remoto executa chpasswd
para alterar as senhas conforme especificado em stdin.
A opção -e
informa chpasswd
que as senhas já estão criptografadas. Sem essa opção, ele criptografaria novamente as senhas fornecidas.
chpasswd
irá reclamar no stderr sobre qualquer nome de usuário que não exista no sistema remoto, mas ainda mudará as senhas dos nomes de usuário que existirem. O stderr de chpasswd
pode ser redirecionado para / dev / null como mostrado acima.
OBSERVAÇÃO: seria melhor canalizar o stderr para um script que reduza apenas o & esperado; Inofensivo "nome de usuário não existe" erros enquanto ainda exibindo outros erros. Na minha VM de teste, os erros gerados por chpasswd
para usuários inexistentes são assim:
# printf '%s\n' "foo:bar" "xyzzy:fool" | chpasswd
chpasswd: (user foo) pam_chauthtok() failed, error:
Authentication token manipulation error
chpasswd: (line 1, user foo) password not changed
chpasswd: (user xyzzy) pam_chauthtok() failed, error:
Authentication token manipulation error
chpasswd: (line 2, user xyzzy) password not changed