#!../expect -- # passmass: change password on many machines # Synopsis: passmass host1 host2 host3 .... # Don Libes - March 11, 1991 # Description: Change passwords on the named machines. # # You are prompted for old/new passwords. (If you are changing root # passwords and have equivalencing, the old password is not used and may be # omitted.) # # Additional arguments may be used for fine tuning. They affect all hosts # which follow until another argument overrides. # # -user User whose password will be changed. By default, the current # user is used. # -rlogin Use rlogin to access host. (default) # -telnet Use telnet to access host. # -program Next argument is taken as program to run to set password. # Default is "passwd". Other common choices are "yppasswd" and # "set passwd" (e.g., VMS hosts). # -prompt Next argument is taken as a prompt suffix pattern. This allows # the script to know when the shell is prompting. The default is # "# " for root and "% " for non-root accounts. # -timeout Next argument is number of seconds to wait for responses. # Default is 30 but some systems can be much slower logging in. # The best way to run this is to put the command in a one-line shell script # or alias. (Presumably, the set of hosts and parameters will rarely change.) # Then run it whenever you want to change your passwords on all the hosts. exp_version -exit 5.0 if $argc==0 { send_user "usage: $argv0 host1 host2 host3 . . .\n" exit } expect_before -i $user_spawn_id \003 exit proc badhost {host emsg} { global badhosts send_user "\r\n\007password not changed on $host - $emsg\n\n" if 0==[llength $badhosts] { set badhosts $host } else { set badhosts [concat $badhosts $host] } } # set defaults set login "rlogin" set program "passwd" set user [exec whoami] set timeout 1000000 stty -echo send_user "old password: " expect_user -re "(.*)\n" send_user "\n" set oldpassword $expect_out(1,string) send_user "new password: " expect_user -re "(.*)\n" send_user "\n" set newpassword $expect_out(1,string) send_user "retype new password: " expect_user -re "(.*)\n" set newpassword2 $expect_out(1,string) send_user "\n" stty echo trap exit SIGINT if ![string match $newpassword $newpassword2] { send_user "mismatch - password unchanged\n" exit } #send_user "want to see new password you just typed? (y|n) " #expect_user "*\n" # #if [string match "y" [lindex $expect_match 0 c]] { # send_user "password is <$newpassword>\nproceed? (y|n) " # expect_user "*\n" # if ![string match "y" [lindex $expect_match 0 c]] exit #} set timeout 30 set badhosts {} for {set i 0} {$i<$argc} {incr i} { set arg [lindex $argv $i] switch -- $arg \ "-user" { incr i set user [lindex $argv $i] continue } "-prompt" { incr i set prompt [lindex $argv $i] continue } "-rlogin" { set login "rlogin" continue } "-telnet" { set login "telnet" continue } "-program" { incr i set program [lindex $argv $i] continue } "-timeout" { incr i set timeout [lindex $argv $i] continue } set host $arg if [string match $login "rlogin"] { set pid [spawn rlogin $host -l $user] } else { set pid [spawn telnet $host] expect -re "(login|Username):.*" { send "$user\r" } } if ![info exists prompt] { if [string match $user "root"] { set prompt "# " } else { set prompt "(%|\\\$) " } } set logged_in 0 for {} 1 {} { expect "Password*" { send "$oldpassword\r" } eof { badhost $host "spawn failed" break } timeout { badhost $host "could not log in (or unrecognized prompt)" exec kill $pid expect eof break } -re "incorrect|invalid" { badhost $host "bad password or login" exec kill $pid expect eof break } -re $prompt { set logged_in 1 break } } if (!$logged_in) { wait continue } send "$program\r" expect "Old password*" { send "$oldpassword\r" expect "Sorry*" { badhost $host "old password is bad?" continue } "password:" } -re "(n|N)ew password:" send "$newpassword\r" expect -re "not changed|unchanged" { badhost $host "new password is bad?" continue } -re "(password|Verification|Verify|again):.*" send "$newpassword\r" expect -re "(not changed|incorrect|choose new).*" { badhost $host "password is bad?" continue } -re "$prompt" send_user "\n" close wait } if [llength $badhosts] {send_user "\nfailed to set password on $badhosts\n"}