#!/usr/bin/expect -f # # pwchanger - A simple expect script to update passwords # # pwchanger uses / relies on the following things: # # - A fully functional ssh config including key based authentication # - PWVault storage of passwords. # # Turn off the display to hide the passwords sent to the remote system. #log_user 0 ## Read the command line parameter(s) set host [lindex $argv 0] set newPass "[exec pwvault .all/current]\r" set oldPass "[exec pwvault .all/$host]\r" set timeout 60 if {$newPass eq $oldPass} { puts "The old and new passwords are the same. Exit 2" exit 2 } puts "Change the password for $host." # Spawn the remote passwd command. spawn -noecho ssh -t -o BatchMode=yes $host passwd while 1 { expect { "(current) UNIX password:" { send $oldPass } "Enter existing login password:" { send $oldPass } "Enter login password:" { send $oldPass } "Old password:" { send $oldPass } "Old Password:" { send $oldPass } "Password was recently used and is not valid for reuse" { close; puts ""; break } "Enter new password:" { send $newPass } "Enter the new password again:" { send $newPass } "new password:" { send $newPass } "new Password:" { send $newPass } "New password:" { send $newPass } "New Password:" { send $newPass } "New UNIX password:" { send $newPass } "Re-enter new password:" { send $newPass } "Re-enter new Password:" { send $newPass } "Re-type new password:" { send $newPass } "Retype new password:" { send $newPass } "Retype new UNIX password:" { send $newPass } "Password:" { send $oldPass } eof { break } } } # Check the results of the remote passwd command. catch wait result set rc [lindex $result 3] if {$rc} { puts stderr "Error changing the password for $host." # Work around the broken systems that return a non-zero EL after resetting passwords. #exit 1 } puts "Testing the new password for $host." # Spawn the remote true command with out PubkeyAuth to # test to see if the password was successfully changed. spawn -noecho ssh -o PubkeyAuthentication=no -o NumberOfPasswordPrompts=1 $host true while 1 { expect { "Password:" { send "$newPass" } "password:" { send "$newPass" } eof { break } } } # Check the results of the remote true command. catch wait result set rc [lindex $result 3] if {$rc} { puts stderr "Error using the new password." puts stderr "Old: $oldPass" puts stderr "New: $newPass" exit 1 } puts "Updating the stored password for $host." # Update the local password store exec pwvault .all/current | pwvault update .all/$host puts "Done changing the password for $host."