]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | ||
3 | /** | |
4 | * LDAP PHP Change Password Webpage | |
5 | * @author: Matt Rude <http://mattrude.com> | |
6 | * @website: http://technology.mattrude.com/2010/11/ldap-php-change-password-webpage/ | |
7 | * | |
8 | * | |
9 | * GNU GENERAL PUBLIC LICENSE | |
10 | * Version 2, June 1991 | |
11 | * | |
12 | * Copyright (C) 1989, 1991 Free Software Foundation, Inc., | |
13 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
14 | * Everyone is permitted to copy and distribute verbatim copies | |
15 | * of this license document, but changing it is not allowed. | |
16 | */ | |
17 | ||
18 | $message = array(); | |
19 | $message_css = ""; | |
20 | ||
21 | function changePasswordLDAP($con, $user_dn, $newPassword){ | |
22 | global $message; | |
23 | $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4); | |
24 | $encoded_newPassword = "{SSHA}" . base64_encode(pack("H*", sha1($newPassword.$salt)).$salt); | |
25 | ||
26 | $entry = array(); | |
27 | $entry["userPassword"] = "$encoded_newPassword"; | |
28 | ||
29 | if (ldap_modify($con,$user_dn,$entry) === false){ | |
30 | $error = ldap_error($con); | |
31 | $errno = ldap_errno($con); | |
32 | $message[] = "$errno - $error"; | |
33 | return false; | |
34 | } else { | |
35 | return true; | |
36 | } | |
37 | } | |
38 | ||
39 | function changePasswordSQL($user_realm, $newPassword) { | |
40 | global $message; | |
41 | ||
42 | foreach(["PGUSER", "PGPASSWORD", "PGDATABASE", "PGHOST"] as $k) { | |
43 | if (isset($_SERVER[$k]) && !isset($_ENV[$k])) { | |
44 | putenv("${k}=" . $_SERVER[$k]); | |
45 | } | |
46 | } | |
47 | $con = pg_connect(""); | |
48 | $result = pg_query_params($con, "WITH newsalt as (SELECT gen_random_bytes(4)) UPDATE ldap_users SET password = encode(digest( convert_to($1, 'UTF8') || (SELECT * FROM newsalt), 'sha1'), 'hex'), mechanism = 'SSHA', salt = (SELECT * FROM newsalt) where login || '@' || realm = $2", array($newPassword, $user_realm)); | |
49 | if (!$result) { | |
50 | $message[] = "Error when accessing database"; | |
51 | return false; | |
52 | } else { | |
53 | return true; | |
54 | } | |
55 | } | |
56 | ||
57 | function changePassword($user,$oldPassword,$newPassword,$newPasswordCnf){ | |
58 | global $message; | |
59 | global $message_css; | |
60 | ||
61 | $server = "ldaps://ldap.immae.eu"; | |
62 | ||
63 | error_reporting(0); | |
64 | $con = ldap_connect($server); | |
65 | ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3); | |
66 | ||
67 | $user_dn = "uid=$user,ou=users,dc=immae,dc=eu"; | |
68 | ||
69 | if (ldap_bind($con, $user_dn, $oldPassword) === false) { | |
70 | $user_dn = "uid=$user,ou=group_users,dc=immae,dc=eu"; | |
71 | if (ldap_bind($con, $user_dn, $oldPassword) === false) { | |
72 | $message[] = "Error E101 - Current Username or Password is wrong."; | |
73 | return false; | |
74 | } | |
75 | } | |
76 | if ($newPassword != $newPasswordCnf ) { | |
77 | $message[] = "Error E102 - Your New passwords do not match!"; | |
78 | return false; | |
79 | } | |
80 | if (strlen($newPassword) < 6 ) { | |
81 | $message[] = "Error E103 - Your new password is too short.<br/>Your password must be at least 6 characters long."; | |
82 | return false; | |
83 | } | |
84 | ||
85 | $user_search = ldap_search($con,"dc=immae,dc=eu","(uid=$user)"); | |
86 | $auth_entry = ldap_first_entry($con, $user_search); | |
87 | ||
88 | $mail_address = ldap_get_values($con, $auth_entry, "mail")[0]; | |
89 | $first_name = ldap_get_values($con, $auth_entry, "givenName")[0]; | |
90 | $existing_password = ldap_get_values($con, $auth_entry, "userPassword")[0]; | |
91 | if (substr($existing_password, 0, 6) == "{SASL}") { | |
92 | $result = changePasswordSQL(substr($existing_password, 6), $newPassword); | |
93 | } else { | |
94 | $result = changePasswordLDAP($con, $user_dn, $newPassword); | |
95 | } | |
96 | ||
97 | if (!$result) { | |
98 | $message[] = "E201 - Your password cannot be changed, please contact the administrator."; | |
99 | } else { | |
100 | $message_css = "yes"; | |
101 | mail($mail_address,"Password change notice","Dear $first_name, | |
102 | Your password on https://tools.immae.eu/ldap_password.php for account $user was just changed. | |
103 | If you did not make this change, please contact me. | |
104 | If you were the one who changed your password, you may disregard this message. | |
105 | ||
106 | Thanks | |
107 | -- | |
108 | Immae / Ismaƫl", "From: " . getenv("CONTACT_EMAIL")); | |
109 | $message[] = "The password for $user has been changed.<br/>An informational email has been sent to $mail_address.<br/>Your new password is now fully active."; | |
110 | } | |
111 | } | |
112 | ||
113 | ?> | |
114 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
115 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
116 | <head> | |
117 | <title>Password Change Page</title> | |
118 | <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
119 | <link rel="stylesheet" href="https://assets.immae.eu/skeleton/2.0.4/skeleton.min.css" integrity="sha256-2YQRJMXD7pIAPHiXr0s+vlRWA7GYJEK0ARns7k2sbHY=" crossorigin="anonymous" /> | |
120 | <style type="text/css"> | |
121 | body { font-family: Verdana,Arial,Courier New; margin: auto; } | |
122 | ||
123 | .msg_yes { margin: 0 auto; text-align: center; color: green; background: #D4EAD4; border: 1px solid green; border-radius: 10px; margin: 2px; } | |
124 | .msg_no { margin: 0 auto; text-align: center; color: red; background: #FFF0F0; border: 1px solid red; border-radius: 10px; margin: 2px; } | |
125 | </style> | |
126 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
127 | </head> | |
128 | <body> | |
129 | <div class="container"> | |
130 | <form action="<?php print $_SERVER['PHP_SELF']; ?>" name="passwordChange" method="post"> | |
131 | <h3>Password Change Page</h3> | |
132 | <?php | |
133 | if (isset($_POST["submitted"])) { | |
134 | echo '<div class="row">'; | |
135 | changePassword($_POST['username'],$_POST['oldPassword'],$_POST['newPassword1'],$_POST['newPassword2']); | |
136 | global $message_css; | |
137 | if ($message_css == "yes") { | |
138 | echo '<div class="msg_yes">'; | |
139 | } else { | |
140 | echo '<div class="msg_no">'; | |
141 | $message[] = "Your password was not changed."; | |
142 | } | |
143 | foreach ( $message as $one ) { echo "<p>$one</p>"; } | |
144 | ?></div></div><?php | |
145 | } ?> | |
146 | <div class="row"> | |
147 | <div class="one-third column"><label for="username">Username</label></div> | |
148 | <div class="two-thirds column"><input id="username" name="username" type="text" autocomplete="off" /></div> | |
149 | </div> | |
150 | <div class="row"> | |
151 | <div class="one-third column"><label for="oldPassword">Current password</label></div> | |
152 | <div class="two-thirds column"><input id="oldPassword" name="oldPassword" type="password" /></div> | |
153 | </div> | |
154 | <div class="row"> | |
155 | <div class="one-third column"><label for="newPassword1">New password</label></div> | |
156 | <div class="two-thirds column"><input id="newPassword1" name="newPassword1" type="password" /></div> | |
157 | </div> | |
158 | <div class="row"> | |
159 | <div class="one-third column"><label for="newPassword2">New password (again)</label></div> | |
160 | <div class="two-thirds column"><input id="newPassword2" name="newPassword2" type="password" /></div> | |
161 | </div> | |
162 | <div class="row"> | |
163 | <div class="column"> | |
164 | <input name="submitted" type="submit" value="Change Password"/> | |
165 | </div> | |
166 | </div> | |
167 | </form> | |
168 | </div> | |
169 | </body> | |
170 | </html> |