summaryrefslogtreecommitdiff
path: root/web/src/cgi.tcl-1.10/example/passwd.cgi
blob: 85c181743a42145ac26b5d78202d6caa6a13d9bd (plain)
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."
	}
    }
}