2010-06-20 4 views
8

Ich möchte eine Möglichkeit, mein Passwort auf einem Remote Ubuntu 10.4 Box mit zu aktualisieren.Ändern Unix-Passwort von der Befehlszeile über Python/Fabric

Ich würde meine erwarten fabfile.py etwas würde wie folgt aussehen:

davon
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)) 

Leider lässt ich weiß, der einzige Befehl ein das Passwort passwd ist ändern, und auf Ubuntu 10.4 scheint es nicht zu sein, Möglichkeit, das neue (oder alte) Passwort als Argument an passwd zu übergeben.

Welchen Befehl könnte man verwenden, um das Passwort eines Benutzers auf Ubuntu 10.4 über fabric zu ändern?

EDIT: Ich habe einen Blick auf usermod -p hat, und das funktionieren kann, aber es ist nicht von der man-Seite empfohlen.

EDIT: Aus irgendeinem Grund usermod -p wurde auch nicht über Gewebe arbeiten.

Wie gut, habe ich versucht, eine (etwas unsicher) Variation MikeJ Antwort, die das Problem zu lösen hat:

# 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") 

eine sehr elegante Lösung, aber es funktioniert es nicht.

Vielen Dank für das Lesen.

Brian

+0

anzumerken, dass auf Lucid, das Argument zu 'usermod -p' ist„das verschlüsselte Passwort, wie von Krypta (3) zurück“unter Verwendung von SHA-512 nicht der Klartext. Der Vorbehalt auf der Usermod-Seite entspricht der Aussage "Sie würden den (normalerweise versteckten) gehashten Inhalt von/etc/shadow für eine kurze Zeit in die Prozesstabelle einfügen", was je nach Ihren Sicherheitsanforderungen nicht alles sein kann Aufschlussreich. – msw

Antwort

14

Sie könnten die neuen und alten Passwörter in passwdecho Verwendung zuzuführen z.B.

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

(die -e Option für echo ermöglicht Interpretation von Backslash entkommt so werden die Zeilenumbrüche als solche interpretiert)

+0

@Mikej - danke für die Antwort. Ich habe es versucht, aber ich habe Probleme mit der Flucht. Insbesondere 'run (" echo -e \ "% s \\ n% s \\ n% s \" |/usr/bin/passwd "% (alt_pw, neu_pw, neu_pw))' funktioniert nicht (dh gibt zurück "UNIX password: passwd: Authentifizierungs-Token-Manipulationsfehler") –

+0

Möglicherweise müssen Sie die \ (einmal für Python und einmal für echo) z '\\\' n' für jede neue Zeile – mikej

+0

@Mikej: Wenn ich dies von der Befehlszeile aus ausführen, funktioniert es gut. Aber wenn ich es über 'Fabric 'führe, bekomme ich Folgendes:' UNIX-Passwort: Neues UNIX-Passwort eingeben: Neues UNIX-Passwort erneut eingeben: passwd: Authentifizierungs-Token-Manipulationsfehler' –

10

Der Trick ist crypt eine Kombination aus usermod und Python zu verwenden, um Ihr Passwort zu ändern:

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

Schön! Ich möchte hinzufügen, dass es eine gute Idee ist, getpass anstelle von prompt zu verwenden, wenn Sie nach dem Passwort fragen. –

+0

@ManuelCeron guten Ruf! – Roshambo

+1

Salz für 'crypt' kann nur zwei Zeichen aus [a-zA-Z0-9./] enthalten, also ist 'salt' dasselbe wie 'sa', siehe [docs] (http://docs.python.org /2/library/crypt.html#crypt.crypt). – schemacs

3

Aus Interesse muss ich eine ähnliche Aufgabe auf einer Sammlung von Solaris-Boxen (fügen Sie eine ganze Menge von Benutzern, stellen Sie ihr Passwort). Solaris usermod hat keine Option --password. In der Vergangenheit habe ich Expect verwendet, aber das Schreiben von Expect-Skripten kann sehr schmerzhaft sein.

Also dieses Mal werde ich Python crypt.crypt verwenden, bearbeiten Sie/etc/shadow direkt (mit Backups, natürlich). http://docs.python.org/release/2.6.1/library/crypt.html

Kommentatoren haben vorgeschlagen, verschiedene Echo-Beschwörungen zu verwenden, die an passwd weitergeleitet werden. AFAIK das wird nie funktionieren, da passwd programmiert ist, Eingaben von stdin zu ignorieren und nur Eingaben von einem interaktiven tty zu akzeptieren. Siehe http://en.wikipedia.org/wiki/Expect

5

Ich benutze chpasswd auf Ubuntu 11.04

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

Hinweis: Normalerweise ist dieses Muster nicht:

$ sudo echo bla | restricted_command 

weil nur die 'Echo' erhält erweiterte Rechte, nicht die 'restricted_command'.

aber hier funktioniert es, weil, wenn fabric.api.sudo caled ist mit shell = True (Standard), Stoff den Befehl wie folgt zusammensetzt:

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

sudo laicht eine neue Shell (/ bin/bash), die mit root-Rechten ausgeführt werden, und dann führt die eskalierte Shell den Befehl aus.

Ein anderer Weg, mit Sudo zu Rohr sudo tee verwenden:

Verwandte Themen