Skip to content

Instantly share code, notes, and snippets.

@jackhftang
Last active May 25, 2024 03:24
Show Gist options
  • Save jackhftang/2592bb16971e4b60ce32022c48cc74e1 to your computer and use it in GitHub Desktop.
Save jackhftang/2592bb16971e4b60ce32022c48cc74e1 to your computer and use it in GitHub Desktop.
LDAP PHP Change Password Page (modified). Original can be found at https://gist.github.com/mattrude/657334
<?php
/**
* LDAP PHP Change Password Webpage
*
* Copyright (C) 2010 Matt Rude <http://mattrude.com>
* Copyright (C) 2019 Jack Tang <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
$message = array();
function changePassword($user, $oldPassword, $newPassword, $newPasswordCnf)
{
global $message;
$server = '127.0.0.1';
# base DN for all users
$dn = 'ou=users,dc=example,dc=com';
# bind DN for search users, need to have `read` permission on attributes: uid, mail, pwdaccountlockedtime
$bindDn = 'uid=readonly,dc=example,dc=com';
$bindDnPwd = 'secret';
error_reporting(0);
$con = ldap_connect($server);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
// bind rdn and find user by uid
if (ldap_bind($con, $bindDn, $bindDnPwd) === false) {
$message[] = "Error E201 - Unable to connect to server, you may not change your password at this time, sorry.";
return false;
}
$userSearch = ldap_search($con, $dn, "(|(uid=$user)(mail=$user))");
$userGet = ldap_get_entries($con, $userSearch);
if (!$userGet) {
$message[] = "Error E202 - Unable to connect to server, you may not change your password at this time, sorry.";
return false;
}
// find the first match and search again
$userEntry = ldap_first_entry($con, $userSearch);
$userDn = ldap_get_dn($con, $userEntry);
$userId = $userGet[0]["uid"][0];
$userSearchArray = array("pwdaccountlockedtime");
$userSearchFilter = "(|(uid=$userId)(mail=$user))";
$userSearchOpt = ldap_search($con, $userDn, $userSearchFilter, $userSearchArray);
$userGetOpt = ldap_get_entries($con, $userSearchOpt);
$pwdAccountLockedTime = $userGetOpt[0]["pwdaccountlockedtime"][0];
// Start the testing
if ($pwdAccountLockedTime) {
$message[] = "Error E101 - Your Account is Locked Out!!! Please contact the administrator to unlock.";
return false;
}
if (ldap_bind($con, $userDn, $oldPassword) === false) {
$message[] = "Error E101 - Current Username or Password is wrong.";
return false;
}
if ($newPassword != $newPasswordCnf) {
$message[] = "Error E102 - Your New passwords do not match!";
return false;
}
$encoded_newPassword = "{SHA}" . base64_encode(pack("H*", sha1($newPassword)));
if (strlen($newPassword) < 8) {
$message[] = "Error E103 - Your new password is too short.<br/>Your password must be at least 8 characters long.";
return false;
}
if (!preg_match("/[0-9]/", $newPassword)) {
$message[] = "Error E104 - Your new password must contain at least one number.";
return false;
}
if (!preg_match("/[a-zA-Z]/", $newPassword)) {
$message[] = "Error E105 - Your new password must contain at least one letter.";
return false;
}
if (!preg_match("/[A-Z]/", $newPassword)) {
$message[] = "Error E106 - Your new password must contain at least one uppercase letter.";
return false;
}
if (!preg_match("/[a-z]/", $newPassword)) {
$message[] = "Error E107 - Your new password must contain at least one lowercase letter.";
return false;
}
// And Finally, Change the password
$entry = array();
$entry["userPassword"] = "$encoded_newPassword";
if (ldap_modify($con, $userDn, $entry)) {
$message[] = "The password for $userId has been changed.<br/>Your new password is now fully Active.";
} else {
$error = ldap_error($con);
$errno = ldap_errno($con);
$message[] = "E201 - Your password cannot be change, please contact the administrator.";
$message[] = "$errno - $error";
$message[] = "Your password was not changed.";
}
return true;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Password Change Page</title>
<style type="text/css">
body {
font-family: Verdana, Arial, Courier New, serif;
font-size: 0.7em;
}
th {
text-align: right;
padding: 0.8em;
}
#container {
text-align: center;
width: 500px;
margin: 5% auto;
}
.msg_yes {
text-align: center;
color: green;
background: #D4EAD4;
border: 1px solid green;
border-radius: 10px;
margin: 2px;
}
.msg_no {
text-align: center;
color: red;
background: #FFF0F0;
border: 1px solid red;
border-radius: 10px;
margin: 2px;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<div id="container">
<h2>Password Change Page</h2>
<p>
Your new password must be 8 characters long or longer and have at least:<br/>
one capital letter, one lowercase letter, &amp; one number.<br/>
You must use a new password, your current password<br/>
can not be the same as your new password.
</p>
<?php
if (isset($_POST["submitted"])) {
$ok = changePassword($_POST['username'], $_POST['oldPassword'], $_POST['newPassword1'], $_POST['newPassword2']);
if ($ok) {
echo '<div class="msg_yes">';
} else {
echo '<div class="msg_no">';
}
foreach ($message as $msg) {
echo "<p>$msg</p>";
}
echo '</div>';
}
?>
<form method="POST" action="/">
<table style="width: 400px; margin: 0 auto;">
<tr>
<th><label for="username"> Username or Email Address:</label></th>
<td><input id="username" name="username" type="text" size="20px"/></td>
</tr>
<tr>
<th><label for="oldPassword">Current password:</label></th>
<td><input id="oldPassword" name="oldPassword" size="20px" type="password"/></td>
</tr>
<tr>
<th><label for="newPassword1">New password:</label></th>
<td><input id="newPassword1" name="newPassword1" size="20px" type="password"/></td>
</tr>
<tr>
<th><label for="newPassword2">New password (again):</label></th>
<td><input id="newPassword2" name="newPassword2" size="20px" type="password"/></td>
</tr>
<tr>
<td colspan="2" style="text-align: center;">
<input name="submitted" type="submit" value="Change Password"/>
<button onclick="location.reload()">Cancel</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
@JaymarkCruz
Copy link

i follow all the codes above and i'm getting "E201 - Your password cannot be change, please contact the administrator.
19 - Constraint violation"

Please help :D

@jackhftang
Copy link
Author

It is likely that your setting of these two variables are wrong.
$bindDn = 'uid=readonly,dc=example,dc=com';
$bindDnPwd = 'secret';

@JaymarkCruz
Copy link

i'm pretty sure it correct, i use it also in my log-in function and bind works properly.

@jackhftang
Copy link
Author

ldap_bind is native php function. There is not much custom logic here. One thing to note is that it is by default connected to port 389 (ldap, not ldaps). if $server is also also correct, then I would guess it is something else.

@naidola1
Copy link

I tried to use the script but I keep on getting error 'User not found and/or password incorrect".

I tried to bind using binddn and bindpw but no success. Any help would be appreciated.

@naidola1
Copy link

Also I am using ldap/389 for initial testing..and not the secure port

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment