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
|
#!/depot/path/expect --
# This is a CGI script to process requests created by the accompanying
# passwd.html form. This script is pretty basic, although it is
# reasonably robust. (Purposely intent users can make the script bomb
# by mocking up their own HTML form, however they can't expose or steal
# passwords or otherwise open any security holes.) This script doesn't
# need any special permissions or ownership.
#
# With a little more code, the script can do much more exotic things -
# for example, you could have the script:
#
# - telnet to another host first (useful if you run CGI scripts on a
# firewall), or
#
# - change passwords on multiple password server hosts, or
#
# - verify that passwords aren't in the dictionary, or
#
# - verify that passwords are at least 8 chars long and have at least 2
# digits, 2 uppercase, 2 lowercase, or whatever restrictions you like,
# or
#
# - allow short passwords by responding appropriately to passwd
#
# and so on. Have fun!
#
# Don Libes, NIST
package require cgi
cgi_eval {
source example.tcl
source passwd.tcl
cgi_input
# Save username as cookie (see comment in passwd-form script) so that the
# next time users load the form, their username will already be filled in.
# If cookies bother you, simply remove this entire cgi_http_head command.
cgi_http_head {
cgi_content_type text/html
if {0==[catch {cgi_import login}]} {
cgi_export_cookie login expires=never
}
}
cgi_title "Password Change Acknowledgment"
cgi_body {
if {(![info exists login])
|| [catch {cgi_import old}]
|| [catch {cgi_import new1}]
|| [catch {cgi_import new2}]} {
errormsg "This page has been called with input missing. Please \
visit this form by filling out the password change \
request form."
return
}
# Prevent user from sneaking in commands (albeit under their own uid).
if {[regexp "\[^a-zA-Z0-9]" $login char]} {
errormsg "Illegal character ($char) in username."
return
}
log_user 0
# Need to su first to get around passwd's requirement that
# passwd cannot be run by a totally unrelated user. Seems
# rather pointless since it's so easy to satisfy, eh?
# Change following line appropriately for your site.
# (We use yppasswd, but you might use something else.)
spawn /bin/su $login -c "/bin/yppasswd $login"
# This fails on SunOS 4.1.3 (passwd says "you don't have a
# login name") so run on (or telnet first to) host running
# SunOS 4.1.4 or later.
expect {
-re "Unknown (login|id):" {
errormsg "unknown user: $login"
return
} default {
errormsg "$expect_out(buffer)"
return
} "Password:"
}
send "$old\r"
expect {
"unknown user" {
errormsg "unknown user: $login"
return
} "Sorry" {
errormsg "Old password incorrect"
return
} default {
errormsg "$expect_out(buffer)"
return
} "Old password:"
}
send "$old\r"
expect "New password:"
send "$new1\r"
expect "New password:"
send "$new2\r"
expect -re (.+)\r\n {
set error $expect_out(1,string)
}
close
wait
if {[info exists error]} {
errormsg "$error"
} else {
successmsg "Password changed successfully."
}
}
}
|