Repository navigation
Expand file tree
/
Copy pathsshchpwd.exp
More file actions
executable file
·313 lines (304 loc) · 9.84 KB
/
Copy pathsshchpwd.exp
File metadata and controls
executable file
·313 lines (304 loc) · 9.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#!/usr/bin/expect -f
#
# /usr/local/bin/sshchpwd.exp
#
# Expect script to change login passwords using SSH, with support for one-time
# tokens (like SecurID), expired passwords (changed before arriving at the
# prompt), on Solaris, AIX, Linux, etc. Password setting on the local system
# is also supported.
#
# License: GPLv3
# License URI: http://www.gnu.org/licenses/gpl.txt
#
# Copyright 2012-2016 Jean-Sebastien Morisset (http://surniaulula.com/)
# Modifications for SCO Openserver 5.0.7 passwords and local passwords:
# Copyright 2020 Kevin R. Bulgrien (https://systemsdesignusa.com/)
#
# Example:
#
# $ export OLD_PASSWORD="oldpwd"
# $ export NEW_PASSWORD="newpwd"
# $ ./sshchpwd {server} {port} {token} {passwd_command}
#
# -or-
#
# $ ./sshchpwd {server} {port} {token} {passwd_command} {oldpwd} {newpwd}
#
# The {server} parameter may incorporate a login username (i.e. user@server).
# When {server} is set to a null string, the password change is done on the
# local system, so {port} and {token} are ignored (and permit null values).
#
# The {port} and {token} command-line parameters are optional. If the server
# uses SecurID (or another one-time password), enter it on the command-line
# as the third parameter.
#
# The {passwd_command} parameter is optional. It supports customizing the
# passwd command. As this script handles only prompts produced by various
# versions of the passwd utility while actually changing a password, this
# parameter is primarily intended to tweak the command as needed to supply
# command-line arguments, or, for example, to prefix the command with sudo.
# In the case of sudo, however, as this script is not sudo-aware, sudo must
# permit the login user to run passwd without first retyping their password.
# (See the sudo "nopasswd" configuration option.) If any prior optional
# parameter is not needed, use empty quotes ("") as a placeholder for
# unused optional parameters.
#
# If supplied, both {oldpwd} and {newpwd} are required, and, unless {newpwd}
# is null, OLD_PASSWORD and NEW_PASSWORD environment variables are ignored.
#
# Example:
#
# $ export OLD_PASSWORD=""
# $ export NEW_PASSWORD="newpwd"
# $ ./sshchpwd login@hostname "" "login_password" "sudo passwd username"
#
# In the case of changing another user's password, OLD_PASSWORD, though not
# likely required, is defined to avoid an error (blank value is ok), and the
# ssh login user's password is supplied as {token} and not as an OLD_PASSWORD.
set timeout 15
set server [lindex $argv 0]
set port [lindex $argv 1]
set tokpwd [lindex $argv 2]
set passwd [lindex $argv 3]
set oldpwd [lindex $argv 4]
set newpwd [lindex $argv 5]
# When passwords are supplied as command-line arguments, do not bother reading
# the environment variables unless the new password is null.
#
if { [string length "$newpwd"] == 0 } {
set newpwd $env(NEW_PASSWORD)
if { [string length "$oldpwd"] == 0 } {
set oldpwd $env(OLD_PASSWORD)
}
}
set prompt "\[>%\\$#\] "
if { $port == "" } { set port "22" }
if { $tokpwd == "" } { set tokpwd $oldpwd }
if { $passwd == "" } { set passwd "passwd" }
# Avoid ssh-to-remote-server if the server parameter was left blank. This
# allows the script to dual-purpose as a scriptable local password setter.
#
if { [string length $server] == 0 } {
send_user "setting a local password\n"
spawn $env(SHELL)
} else {
send_user "connecting to $server on port $port\n"
spawn ssh -p $port $server
# Mission of this first expect - get to the shell command prompt. If the
# password is expired and we have to change it before getting to the prompt,
# then exit 0 (success).
expect {
"(yes/no)? " {
send_user " (detected unknown host key - accepting)\n"
send "yes\n"
send_user " (continuing expect loop)\n"
exp_continue
}
"assword:" {
send_user " (detected password login prompt - possibly token)\n"
send "$tokpwd\n"
expect {
" UNIX password:" {
send_user " (detected additional password prompt - old password)\n"
send "$oldpwd\n"
send_user " (continuing expect loop)\n"
exp_continue
}
-nocase "old password:" {
send_user " (detected password expired prompt)\n"
send "$oldpwd\n"
send_user " (continuing expect loop)\n"
exp_continue
}
-re "not match the|password mismatch" {
send_user " (assuming expired password change failed)\n"
send "$passwd\n"
expect {
-nocase "old password:" {
send_user " (trying with new password)\n"
send "$newpwd\n"
expect {
-re "\[nN\]ew \[pP\]assword:|\[nN\]ew \[pP\]assword \[aA\]gain:" {
send_user "\nPassword is current.\n"
exit 0
}
"not match the" {
send_user "\nPassword change failed.\n"
exit 1
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
-re "\[nN\]ew \[pP\]assword:|\[nN\]ew \[pP\]assword \[aA\]gain:" {
send "$newpwd\n"
expect {
"between changes." {
send_user "\nPassword change failed.\n"
exit 1
}
-re "\[nN\]ew \[pP\]assword:|\[nN\]ew \[pP\]assword \[aA\]gain:" {
send "$newpwd\n"
expect {
-re "$prompt" {
send_user " (detected shell command prompt)\n"
send_user "Password successfully changed.\n"
exit 0
}
"Connection to " {
send_user " (detected connection closed - assuming password change successful)\n"
send_user "Password successfully changed.\n"
exit 0
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
}
}
"assword:" {
send "$newpwd\n"
expect {
" UNIX password:" {
send_user "\nNew password is expired!\n"
exit 1
}
-nocase "old password:" {
send_user "\nNew password is expired!\n"
exit 1
}
"assword:" {
send_user "\nAutomated login failed.\n"
exit 1
}
-re "$prompt" {
send_user " (detected shell command prompt)\n"
send_user "Password is current.\n"
exit 0
}
default {
send_user "\nAutomated login failed.\n"
exit 1
}
}
}
-re "$prompt" { send_user " (detected shell command prompt)\n" }
}
}
-re "$prompt" { send_user " (detected shell command prompt)\n" }
}
}
send "\n"
expect {
-re "$prompt" {
send_user " (changing password at prompt)\n"
send "$passwd\n"
expect {
-re "\[oO\]ld \[pP\]assword:| UNIX \[pP\]assword:" {
send "$oldpwd\n"
expect {
"You must wait longer" {
send_user "\nPassword change failed.\n"
exit 1
}
-re "not match the|password mismatch" {
send "$passwd\n"
expect {
-nocase "old password:" {
send_user " (trying with new password)\n"
send "$newpwd\n"
expect {
-re "\[nN\]ew \[pP\]assword( \[aA\]gain)?:" {
send_user "\nPassword is current.\n"
exit 0
}
"not match the" {
send_user "\nPassword change failed.\n"
exit 1
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
}
}
-re "1..Pick a password" {
# As seen on SCO 5.0.7.
# 1: Pick a password
# 2: Pronounceable password will be generated for you
expect {
-re "Enter choice .default is 1.:" {
send "1\n"
expect {
"Please enter new password:" {
# Ignore; it is not a prompt. "New password:" will follow.
}
}
}
}
}
}
expect {
-re "\[N\]ew \[pP\]assword:|\[pP\]assword \[aA\]gain:" {
send "$newpwd\n"
expect {
"between changes." {
send_user "\nPassword change failed.\n"
exit 1
}
-re "(\[N\]ew|Re-enter) \[pP\]assword( \[aA\]gain)?:" {
send "$newpwd\n"
expect {
-re "$prompt" {
send_user " (detected return to shell command prompt)\n"
send_user "Password successfully changed.\n"
exit 0
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
"BAD PASSWORD" {
send_user "\nPassword change failed.\n"
exit 1
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
default {
send_user "\nPassword change failed.\n"
exit 1
}
}
}
default {
send_user "\nCommand prompt not detected.\n"
if { [string length $server] } {
send_user "\nAutomated login failed.\n"
}
exit 1
}
}