| 1 | #!/bin/sh |
| 2 | # \ |
| 3 | exec expect -- "$0" ${1+"$@"} |
| 4 | # passmass: change password on many machines |
| 5 | # Synopsis: passmass host1 host2 host3 .... |
| 6 | # Don Libes - March 11, 1991 |
| 7 | |
| 8 | # Description: Change passwords on the named machines. |
| 9 | # |
| 10 | # See passmass.man for further info. |
| 11 | |
| 12 | exp_version -exit 5.0 |
| 13 | |
| 14 | if {$argc==0} { |
| 15 | send_user "usage: $argv0 host1 host2 host3 . . .\n" |
| 16 | exit |
| 17 | } |
| 18 | |
| 19 | expect_before -i $user_spawn_id \003 exit |
| 20 | |
| 21 | proc badhost {host emsg} { |
| 22 | global badhosts |
| 23 | |
| 24 | send_user "\r\n\007password not changed on $host - $emsg\n\n" |
| 25 | if {0==[llength $badhosts]} { |
| 26 | set badhosts $host |
| 27 | } else { |
| 28 | set badhosts [concat $badhosts $host] |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | # set defaults |
| 33 | set login "rlogin" |
| 34 | set program "passwd" |
| 35 | set user [exec whoami] |
| 36 | set su 0 |
| 37 | |
| 38 | set timeout -1 |
| 39 | stty -echo |
| 40 | |
| 41 | if {!$su} { |
| 42 | send_user "old password: " |
| 43 | expect_user -re "(.*)\n" |
| 44 | send_user "\n" |
| 45 | set password(old) $expect_out(1,string) |
| 46 | set password(login) $expect_out(1,string) |
| 47 | send_user "new password: " |
| 48 | expect_user -re "(.*)\n" |
| 49 | send_user "\n" |
| 50 | set password(new) $expect_out(1,string) |
| 51 | send_user "retype new password: " |
| 52 | expect_user -re "(.*)\n" |
| 53 | set password(newcheck) $expect_out(1,string) |
| 54 | send_user "\n" |
| 55 | } else { |
| 56 | send_user "login password: " |
| 57 | expect_user -re "(.*)\n" |
| 58 | send_user "\n" |
| 59 | set password(login) $expect_out(1,string) |
| 60 | send_user "root password: " |
| 61 | expect_user -re "(.*)\n" |
| 62 | send_user "\n" |
| 63 | set password(old) $expect_out(1,string) |
| 64 | send_user "new password: " |
| 65 | expect_user -re "(.*)\n" |
| 66 | send_user "\n" |
| 67 | set password(new) $expect_out(1,string) |
| 68 | send_user "retype new password: " |
| 69 | expect_user -re "(.*)\n" |
| 70 | set password(newcheck) $expect_out(1,string) |
| 71 | send_user "\n" |
| 72 | } |
| 73 | |
| 74 | stty echo |
| 75 | trap exit SIGINT |
| 76 | |
| 77 | if ![string match $password(new) $password(newcheck)] { |
| 78 | send_user "mismatch - password unchanged\n" |
| 79 | exit |
| 80 | } |
| 81 | |
| 82 | set timeout -1 |
| 83 | |
| 84 | set badhosts {} |
| 85 | for {set i 0} {$i<$argc} {incr i} { |
| 86 | set arg [lindex $argv $i] |
| 87 | switch -- $arg "-user" { |
| 88 | incr i |
| 89 | set user [lindex $argv $i] |
| 90 | continue |
| 91 | } "-prompt" { |
| 92 | incr i |
| 93 | set prompt [lindex $argv $i] |
| 94 | continue |
| 95 | } "-rlogin" { |
| 96 | set login "rlogin" |
| 97 | continue |
| 98 | } "-slogin" { |
| 99 | set login "slogin" |
| 100 | continue |
| 101 | } "-ssh" { |
| 102 | set login "ssh" |
| 103 | continue |
| 104 | } "-telnet" { |
| 105 | set login "telnet" |
| 106 | continue |
| 107 | } "-program" { |
| 108 | incr i |
| 109 | set program [lindex $argv $i] |
| 110 | continue |
| 111 | } "-timeout" { |
| 112 | incr i |
| 113 | set timeout [lindex $argv $i] |
| 114 | continue |
| 115 | } "-su" { |
| 116 | incr i |
| 117 | set su [lindex $argv $i] |
| 118 | continue |
| 119 | } |
| 120 | |
| 121 | set host $arg |
| 122 | if {[string match $login "rlogin"]} { |
| 123 | set pid [spawn rlogin $host -l $user] |
| 124 | } elseif {[string match $login "slogin"]} { |
| 125 | set pid [spawn slogin $host -l $user] |
| 126 | } elseif {[string match $login "ssh"]} { |
| 127 | set pid [spawn ssh $host -l $user] |
| 128 | } else { |
| 129 | set pid [spawn telnet $host] |
| 130 | expect -nocase -re "(login|username):.*" { |
| 131 | send "$user\r" |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | if ![info exists prompt] { |
| 136 | if {[string match $user "root"]} { |
| 137 | set prompt "# " |
| 138 | } else { |
| 139 | set prompt "(%|\\\$|#) " |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | set logged_in 0 |
| 144 | while {1} { |
| 145 | expect -nocase "password*" { |
| 146 | send "$password(login)\r" |
| 147 | } eof { |
| 148 | badhost $host "spawn failed" |
| 149 | break |
| 150 | } timeout { |
| 151 | badhost $host "could not log in (or unrecognized prompt)" |
| 152 | exec kill $pid |
| 153 | expect eof |
| 154 | break |
| 155 | } -re "incorrect|invalid" { |
| 156 | badhost $host "bad password or login" |
| 157 | exec kill $pid |
| 158 | expect eof |
| 159 | break |
| 160 | } -re $prompt { |
| 161 | set logged_in 1 |
| 162 | break |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | if (!$logged_in) { |
| 167 | wait |
| 168 | continue |
| 169 | } |
| 170 | |
| 171 | if ($su) { |
| 172 | send "su -\r" |
| 173 | expect -nocase "password:" |
| 174 | send "$password(old)\r" |
| 175 | expect "# " |
| 176 | send "$program root\r" |
| 177 | } else { |
| 178 | send "$program\r" |
| 179 | } |
| 180 | |
| 181 | expect -nocase -re "(old|existing login) password:.*" { |
| 182 | send "$password(old)\r" |
| 183 | expect -nocase "sorry*" { |
| 184 | badhost $host "old password is bad?" |
| 185 | continue |
| 186 | } -nocase "password:" |
| 187 | } -nocase -re "new password:" { |
| 188 | # got prompt, fall through |
| 189 | } timeout { |
| 190 | badhost $host "could not recognize prompt for password" |
| 191 | continue |
| 192 | } |
| 193 | send "$password(new)\r" |
| 194 | expect -re "not changed|unchanged" { |
| 195 | badhost $host "new password is bad?" |
| 196 | continue |
| 197 | } -nocase -re "(password|verification|verify|again):.*" |
| 198 | send "$password(new)\r" |
| 199 | expect -nocase -re "(not changed|incorrect|choose new).*" { |
| 200 | badhost $host "password is bad?" |
| 201 | continue |
| 202 | } -re "$prompt" |
| 203 | send_user "\n" |
| 204 | |
| 205 | close |
| 206 | wait |
| 207 | } |
| 208 | |
| 209 | if {[llength $badhosts]} { |
| 210 | send_user "\nfailed to set password on $badhosts\n" |
| 211 | } |