2010-06-20 23 views
8

Vorrei un modo per aggiornare la mia password su una casella remota Ubuntu 10.4 con fabric.Modifica password Unix da riga di comando su Python/Fabric

mi aspetto il mio fabfile.py sarebbe simile a questa:

def update_password(old_pw, new_pw): 
    # Connects over ssh with a public key authentication 
    run("some_passwd_cmd --old %s --new %s" % (old_pw, new_pd)) 

Purtroppo l'unico comando che conosco che permette un cambio della password è passwd, e su Ubuntu 10.4 non sembra essere qualsiasi modo per passare la nuova (o vecchia) password come argomento a passwd.

Quale comando è possibile utilizzare per modificare la password di un utente su Ubuntu 10.4 tramite fabric?

EDIT: Ho avuto uno sguardo al usermod -p, e che può funzionare, ma non è raccomandato dalla pagina man.

MODIFICA: Per qualche motivo, usermod -p non funziona su tessuto.

Così, ho provato una variazione (un po 'insicuro) sulla risposta di mikej che ha risolto il problema:

# connecting & running as root. 
from fabric.api import * 
from fabric.contrib import files 

files.append("%s\n%s" % (passwd, passwd), '.pw.tmp') 
# .pw.tmp: 
# PASSWD 
# PASSWD 

run("passwd %s < .pw.tmp" % user) 

run("rm .pw.tmp") 

Non è una soluzione molto elegante, ma funziona.

Grazie per la lettura.

Brian

+0

noti che sul Lucid, l'argomento '-p' usermod è "La password cifrata, come restituito da crypt (3)" utilizzando SHA-512 non il testo in chiaro L'avvertenza nella pagina usermod equivale a dire "si inserirà il contenuto hash (normalmente nascosto) di/etc/shadow nella tabella di processo per un breve periodo di tempo", che a seconda dei requisiti di sicurezza potrebbe non essere tutto ciò rivelatrice. – msw

risposta

14

Si potrebbe alimentare le nuove e vecchie password in passwd utilizzando echo esempio

echo -e "oldpass\\nnewpass\\nnewpass" | passwd 

(l'opzione -e per echo consente interpretazione dei backslash sfugge quindi i ritorni a capo vengono interpretati come tali)

+0

@ Mikej - grazie per la risposta. Ho provato questo, ma sto avendo quello che penso sia un problema con la fuga. In particolare 'run (" echo -e \ "% s \\ n% s \\ n% s \" |/usr/bin/passwd "% (old_pw, new_pw, new_pw))' non funziona (cioè restituisce "Password UNIX: passwd: errore di manipolazione dei token di autenticazione") –

+0

Potrebbe essere necessario eseguire il doppio escape di \ (una volta per Python e una volta per echo) ad es. '\\\\ n' per ogni nuova riga – mikej

+0

@Mikej: Quando eseguo questo comando dalla riga di comando, funziona correttamente. Tuttavia, quando lo eseguo su 'fabric', ottengo il seguente:' Password UNIX: immettere una nuova password UNIX: ridigitare la nuova password UNIX: passwd: errore di manipolazione dei token di autenticazione ' –

10

Il trucco è quello di utilizzare una combinazione di usermod e Python di crypt per cambiare la password:

from crypt import crypt 
from getpass import getpass 
from fabric.api import * 

def change_password(user): 
    password = getpass('Enter a new password for user %s:' % user) 
    crypted_password = crypt(password, 'salt') 
    sudo('usermod --password %s %s' % (crypted_password, user), pty=False) 
+1

Bello! Vorrei aggiungere che è forse una buona idea usare il getpass invece del prompt quando si chiede la password. –

+0

@ManuelCeron buona chiamata! – Roshambo

+1

salt per 'crypt' può essere solo due caratteri da [a-zA-Z0-9./], quindi 'salt' è uguale a 'sa', vedi [docs] (http://docs.python.org /2/library/crypt.html#crypt.crypt). – schemacs

3

Per motivi di interesse, devo svolgere un'attività simile su una raccolta di scatole Solaris (aggiungere un sacco di utenti, impostare la password). Solaris usermod non ha un'opzione --password, quindi in passato ho usato Expect per farlo, ma scrivere script Expect può essere doloroso.

Quindi questa volta userò Python's crypt.crypt, edit/etc/shadow direttamente (con backup, ovviamente). http://docs.python.org/release/2.6.1/library/crypt.html

I commentatori hanno suggerito di utilizzare vari incantesimi di eco convogliati su passwd. AFAIK non funzionerà mai, dato che passwd è programmato per ignorare input da stdin e accetta solo input da un tty interattivo. Vedi http://en.wikipedia.org/wiki/Expect

5

Io uso chpasswd su Ubuntu 11.04

fabric.api.sudo('echo %s:%s | chpasswd' % (user, pass)) 

Nota: Normalmente questo modello non funziona:

$ sudo echo bla | restricted_command 

perché solo il 'echo' ottiene privilegi elevati, non il 'restricted_command'.

Tuttavia, qui funziona perché quando si fabric.api.sudo caled con shell = True (impostazione predefinita), il tessuto assembla il comando come questo:

$ sudo -S -p <sudo_prompt> /bin/bash -l -c "<command>" 

sudo genera una nuova shell (/ bin/bash), in esecuzione con i privilegi di root e quindi la shell escalation esegue il comando.

Un altro modo per tubo con sudo è quello di utilizzare sudo tee:

Problemi correlati