|
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'); |