3
|
1 |
<?php
|
|
2 |
|
|
3 |
require('includes/starthere.php');
|
|
4 |
|
|
5 |
if ( !empty($_SERVER['PATH_INFO']) )
|
|
6 |
{
|
|
7 |
if ( count($params = explode('/', $_SERVER['PATH_INFO'])) !== 4 )
|
|
8 |
{
|
|
9 |
redirect('/lostpw');
|
|
10 |
}
|
|
11 |
|
|
12 |
list(,$uid,$timestamp,$token) = $params;
|
|
13 |
|
|
14 |
try
|
|
15 |
{
|
|
16 |
$do_redirect = true;
|
|
17 |
if ( !preg_match('/^[a-z0-9]{3,32}$/', $uid) ||
|
|
18 |
!preg_match('/^[a-f0-9]{8}$/', $timestamp) ||
|
|
19 |
!preg_match('/^[a-f0-9]{40}$/', $token) )
|
|
20 |
throw new Exception("Request format is invalid");
|
|
21 |
|
|
22 |
$ts_dec = hexdec($timestamp);
|
|
23 |
|
|
24 |
if ( hash_hmac('sha1', "$uid%$ts_dec", $hmac_secret) !== $token )
|
|
25 |
throw new Exception("Request token is invalid");
|
|
26 |
|
|
27 |
if ( abs(time() - $ts_dec) > (12 * 3600) )
|
|
28 |
throw new Exception("This link has expired. Please request another password reset.");
|
|
29 |
|
|
30 |
$userinfo = ldap_get_user($uid);
|
|
31 |
|
|
32 |
// handle a submit?
|
|
33 |
$do_redirect = false;
|
|
34 |
if ( !empty($_POST['password']) )
|
|
35 |
{
|
|
36 |
if ( ($result = test_password($_POST['password'])) !== true )
|
|
37 |
throw new Exception("Your new password $result.");
|
|
38 |
|
|
39 |
if ( $_POST['password'] !== $_POST['password_confirm'] )
|
|
40 |
throw new Exception("The passwords you entered did not match.");
|
|
41 |
|
|
42 |
if ( reset_password($uid, $_POST['password']) )
|
|
43 |
{
|
|
44 |
queue_message(E_NOTICE, "Your password has been reset. You can now log into the control panel.");
|
|
45 |
redirect('/lostpw');
|
|
46 |
}
|
|
47 |
else
|
|
48 |
{
|
|
49 |
throw new Exception("Internal error when performing password reset.");
|
|
50 |
}
|
|
51 |
}
|
|
52 |
}
|
|
53 |
catch ( Exception $e )
|
|
54 |
{
|
|
55 |
queue_message(E_ERROR, $e->getMessage());
|
|
56 |
if ( $do_redirect )
|
|
57 |
redirect('/lostpw');
|
|
58 |
}
|
|
59 |
|
|
60 |
display_template('resetpw', array(
|
|
61 |
'userinfo' => $userinfo
|
|
62 |
));
|
|
63 |
|
|
64 |
exit;
|
|
65 |
}
|
|
66 |
|
|
67 |
if ( !empty($_POST['email_or_username']) )
|
|
68 |
{
|
|
69 |
try
|
|
70 |
{
|
|
71 |
global $_ldapconn, $ldap_user_basedn;
|
|
72 |
|
|
73 |
$field = strstr($_POST['email_or_username'], '@') ? 'mail' : 'uid';
|
|
74 |
if ( $field == 'uid' && !preg_match('/^[a-z0-9]{3,32}$/', $_POST['email_or_username']) )
|
|
75 |
{
|
|
76 |
throw new Exception("Invalid username. Usernames can only contain 3-32 a-z and 0-9 (all lowercase) characters.");
|
|
77 |
}
|
|
78 |
|
|
79 |
$search_filter = sprintf('(&(%s=%s)(objectClass=posixAccount))', $field, ldap_escape($_POST['email_or_username']));
|
|
80 |
$search_result = ldap_search($_ldapconn, $ldap_user_basedn, $search_filter);
|
|
81 |
|
|
82 |
if ( !$search_result )
|
|
83 |
{
|
|
84 |
throw new Exception(ldap_error($_ldapconn));
|
|
85 |
}
|
|
86 |
|
|
87 |
if ( ldap_count_entries($_ldapconn, $search_result) == 0 )
|
|
88 |
{
|
|
89 |
throw new Exception("Could not find any accounts that matched that $field.");
|
|
90 |
}
|
|
91 |
else if ( ldap_count_entries($_ldapconn, $search_result) > 1 )
|
|
92 |
{
|
|
93 |
throw new Exception("LDAP search query erroneously returned multiple results.");
|
|
94 |
}
|
|
95 |
|
|
96 |
$userinfo = ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result)));
|
|
97 |
|
|
98 |
if ( !isset($userinfo['mail']) )
|
|
99 |
{
|
|
100 |
throw new Exception("No e-mail address is registered to your account. Please contact the administrator to request a password reset.");
|
|
101 |
}
|
|
102 |
|
|
103 |
$mail_censored = $mail = is_array($userinfo['mail']) ? $userinfo['mail'][ count($userinfo['mail']) - 1 ] : $userinfo['mail'];
|
|
104 |
|
|
105 |
// smtp_mail($from, $to, $subject, $body, $headers = '')
|
|
106 |
$reset_link = sprintf('http://%s/lostpw/%s/%08x/%s', gethostname(), $userinfo['uid'], time(), hash_hmac('sha1', "{$userinfo['uid']}%" . time(), $hmac_secret));
|
|
107 |
$email_body = parse_template('emails/lostpw', array(
|
|
108 |
'userinfo' => $userinfo
|
|
109 |
, 'reset_link' => $reset_link
|
|
110 |
, 'ip' => $_SERVER['REMOTE_ADDR']
|
|
111 |
));
|
|
112 |
|
|
113 |
$domainname = strtolower(get_default_kerberos_realm());
|
|
114 |
$mail_result = smtp_mail("accounts@$domainname", $mail, "$domainname password reset", $email_body, "From: $domainname accounts <accounts@$domainname>\r\nTo: {$userinfo['cn']} <$mail>");
|
|
115 |
|
|
116 |
// censor e-mail address to keep deviants from scraping for it
|
|
117 |
if ( $field == 'uid' && preg_match('/^(.)(.*?)(.)@([a-z\.]+)$/', $mail, $match) )
|
|
118 |
$mail_censored = sprintf('%s%s%s@%s', $match[1], str_repeat('.', strlen($match[2])), $match[3], $match[4]);
|
|
119 |
|
|
120 |
if ( $mail_result )
|
|
121 |
{
|
|
122 |
queue_message(E_NOTICE, "Password reset instructions have been mailed to $mail_censored.");
|
|
123 |
}
|
|
124 |
else
|
|
125 |
{
|
|
126 |
throw new Exception("Failed to send e-mail.");
|
|
127 |
}
|
|
128 |
}
|
|
129 |
catch ( Exception $e )
|
|
130 |
{
|
|
131 |
queue_message(E_ERROR, $e->getMessage());
|
|
132 |
}
|
|
133 |
}
|
|
134 |
|
|
135 |
display_template('lostpw');
|