PHP Warning: ldap_bind(): Unable to bind to server: invalid credentials - php

Hello to anyone who's reading this. So let me explain my issue first and I'll attach the code below.
I am using xampp apache server and microsoft active directory domain services on windows server 2016 (both on same VM). I am not a programmer myself particularly but what I am trying to do is using PHP to try to authenticate users in my active directory. At first the code worked and when I entered correct username and password it showed authenticated and this happened only once. Now whenever I try to authenticate, it just keeps giving me the same error that can't bind to ldap server and invalid credentials even though the usernames and passwords are totally correct. Before this I used a code that used one user credential hardcoded to bind and other hardcoded user credentials whos information I am fetching from AD and that code works fine but the other scenario mentioned above doesn't. PLZ Help
(my separate html form file that i am using)
<html>
</head><style>
body {text-align:center;}
form {margin: 0 auto;width:500px;}
input {padding:10px; font-size:20;}
</head></style>
</body>
<h1>Authentication With Active Directory</h1>
<form action="ldap.php" method="post">
<input type="text" name="username" /><br>
<input type="password" name="password" /><br>
<input type="submit" value="login" />
</form>
</body>
</html>
(my php file and both are stored in c:/xampp/htdocs/)
<?php
$ldap_dn = "CN=".$_POST["username"].",DC=example,DC=example";
$ldap_password = $_POST["password"];
$ldap_con = ldap_connect("example");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if(ldap_bind(#$ldap_con,$ldap_dn,$ldap_password))
{
echo "Authenticated";
}
else
{
echo "Invalid Credential";
}
?>
(I have also tried following code to check if connection is established or not and the connection does establish but still it gives invalid credentials. I think there is something wrong with bind in my code but can't figure it out)
<?php
$username; $password;
$ldap_dn = "CN=".$_POST["username"].",DC=ADLAB,DC=local";
$ldap_password = $_POST["password"];
$ldap_con = ldap_connect("ADLAB.ADLAB.local");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($ldap_con)
{
echo "connection established";
if(ldap_bind(#$ldap_con,$ldap_dn,$ldap_password))
{
echo "Authenticated";
}
else
{echo "Invalid Credential";
}
}
else
echo "conection failed";
?>

All Active Directory provides an internal email (ex: username#domain.dom). You can use this to authenticate the user with LDAP bind.
Before use, the values provided by the user, validate it to not contains an invalid character. See preg_match: https://www.php.net/manual/en/function.preg-match
CAUTION: The password must contain one character. If a password is not specified or is empty, an anonymous bind is attempted. See: https://www.php.net/manual/en/function.ldap-bind.php
<?php
$username = $_POST['username'];
$ldap_password = $_POST['password'];
$ldap_dn = $username.'#ADLAB.local';
if (empty($username) || empty($ldap_password) || !preg_match('/^[A-Za-z0-9\-_]$/', $username)) {
die("Invalid credential");
}
$ldap_con = ldap_connect("ADLAB.ADLAB.local");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($ldap_con) { echo "connection established";
if(ldap_bind(#$ldap_con,$ldap_dn,$ldap_password))
{
echo "Authenticated";
}
else
{echo "Invalid Credential";
}
}
else
echo "conection failed";
?>

Related

How can i change from Ldap to Ldaps

I have a functioning code that creats an Ldap connection to an online test server.
<?php
$ldap_dn = "uid=".$_POST["username"].",dc=example,dc=com";
$ldap_password = $_POST["password"];
$ldap_con = ldap_connect("ldap.forumsys.com");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if(#ldap_bind($ldap_con,$ldap_dn,$ldap_password))
{
$_SESSION['username'] = $_POST["username"];
header("Location: Startseite.php");
}
else
{
echo "Invalid Credential";
}
?>
Now i want to change the code to connect to a local Windows server and retrieve data from the active directory.
This connection should be an Ldaps.
Here is the code i tried.
<?php
$ldap_dn = "uid=".$_POST["username"].",dc=ULTIMATE,dc=local";
$ldap_password = $_POST["password"];
$ldap_con = ldap_connect("ldaps://192.168.***.**:636,OU=ULTIMATE,DC=ultimate,DC=local");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if(#ldap_bind($ldap_con,$ldap_dn,$ldap_password))
{
$_SESSION['username'] = $_POST["username"];
header("Location: Startseite.php");
}
else
{
echo "Invalid Credential";
}
?>
And i get the following error
Warning: ldap_connect(): Could not create session handle: Bad parameter to an ldap routine in C:\xampp\htdocs\Kulinarik\ldap.php on line 10
Why is it a bad parameter ?
EDIT
So the Active directory is Passwort protected and the users who want to start the query have no rights.
So i would have to make a Bind with the Credentials of the Sysadmin and then make a query inside the active directory with the Credentials of the users.
Is that right?
Try something like:
$ldap_con = ldap_connect("ldaps://192.168.***.**:636");
Without ,OU=ULTIMATE,DC=ultimate,DC=local part.

Session Login LDAP in PHP with Access Credentials

I am new to PHP and am working on an LDAP login script which will login to the LDAP server using organization credentials, then verify the user's username and password in Active Directory.
There are several good examples, and I've been looking at this one, modifying it to suit my particular needs.
My question is this - in my orgainization's old system (in Classic ASP), there were 2 functions:
BindReturnUPN(username,domain) (this would return the 'userPrincipalName')
BindAuthUPN(upn,password) (this would take the 'userPrincipalName' from the BindReturnUPN function and then return an error number and error description which would determine whether or not the user was logged in.)
In this PHP example, is there any analogy to the 2 functions used in the Classic ASP system?
I've been thinking that I can use the organization log in credentials 'hard coded' to access the LDAP, then search for the matching username and password (from the form), although I'm not sure how the binding would be checked for them. Perhaps an inner if/then condition to check the username/password binding, within the outer organization credentials binding check?
This script is working for me, in showing that I get successfully logged on, yet I'm unsure about the binding and how to check username/password against AD. Thanks for any leads.
Here's my code so far (the $_SESSION['access'] variable determines whether the user is logged in):
login.php
<?php
// initialize session
session_start();
include("authenticate.php");
// check to see if user is logging out
if(isset($_GET['out'])) {
// destroy session
session_unset();
$_SESSION = array();
unset($_SESSION['user'],$_SESSION['access']);
session_destroy();
}
// check to see if login form has been submitted
if(isset($_POST['userLogin'])){
// run information through authenticator
if(authenticate($_POST['userLogin'],$_POST['userPassword']))
{
// authentication passed
header("Location: protected.php");
die();
} else {
// authentication failed
$error = 1;
}
}
// output error to user
if(isset($error)) echo "Login failed: Incorrect user name, password, or rights<br />";
// output logout success
if(isset($_GET['out'])) echo "Logout successful";
?>
<form action="login.php" method="post">
User: <input type="text" name="userLogin" /><br />
Password: <input type="password" name="userPassword" />
<input type="submit" name="submit" value="Submit" />
</form>
authenticate.php
<?php
function authenticate($user, $password) {
if(empty($user) || empty($password)) return false;
// active directory server
$ldap_host = "server.college.school.edu";
// active directory DN (base location of ldap search)
$ldap_dn = "OU=Departments,DC=college,DC=school,DC=edu";
// active directory user group name
$ldap_student_group = "ALL-STUDENTS";
// domain, for purposes of constructing $user
$ldap_usr_dom = 'college\web-account';
$ldap_password = "password_students";
// connect to active directory
$ldap = ldap_connect($ldap_host);
// configure ldap params
ldap_set_option($ldap,LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($ldap,LDAP_OPT_REFERRALS,0);
// verify user and password
//if($bind = #ldap_bind($ldap, $user.$ldap_usr_dom, $password)) {
if($bind = #ldap_bind($ldap, $ldap_usr_dom, $ldap_password)) {
// valid
// check presence in groups
//$filter = "(sAMAccountName=".$user.")";
$filter = "(cn=".$user.")";
$attr = array("memberof");
$result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
$entries = ldap_get_entries($ldap, $result);
ldap_unbind($ldap);
// check groups
$access = 0;
foreach($entries[0]['memberof'] as $grps) {
// is student group, break loop
if(strpos($grps, $ldap_student_group)) { $access = 2; break; }
}
if($access != 0) {
// establish session variables
echo '<br>access'.$access.'<br>';
$_SESSION['user'] = $user;
$_SESSION['access'] = $access;
return true;
} else {
// user has no rights
return false;
}
} else {
// invalid name or password
return false;
}
}
?>
protected.php
<?php
// initialize session
session_start();
echo '<br>access'.$_SESSION['access'].'<br>';
if(!isset($_SESSION['user'])) {
// user is not logged in, do something like redirect to login.php
header("Location: login.php");
die();
}
if($_SESSION['access'] != 2) {
// another example...
// user is logged in but not a student, let's stop him
die("Access Denied");
}
?>
<p>Welcome <?= $_SESSION['user'] ?>!</p>
<p><strong>Secret Protected Content Here!</strong></p>
<p>Mary Had a Little Lamb</p>
<p>Logout</p>

PHP/SQL login form having problems

I'm trying to use the following form to log in, but it always jump to invalid username. Am I missing anything in here?
Database Connection:
$link = mysqli_connect("localhost","X","X","X");
if($link == false) {
die("Error" .mysqli_connect_error());
}
Login Script:
<?php
if (!isset($_POST['submit'])) {
?>
<!-- The HTML login form -->
<form action="<?=$_SERVER['PHP_SELF']?>" method="post">
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" name="submit" value="Login" />
</form>
<?php
} else {
// Include database credentials
include('../db_connect.php');
$mysqli = new mysqli($link);
// check connection
if ($mysqli->connect_errno) {
echo "<p>MySQL error no {$mysqli->connect_errno} : {$mysqli->connect_error}</p>";
exit();
}
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * from admin WHERE admin_email LIKE '{$username}' AND admin_password LIKE '{$password}' LIMIT 1";
$result = $mysqli->query($sql);
if (!$result->num_rows == 1) {
echo "<p>Invalid username/password combination</p>";
} else {
echo "<p>Logged in successfully</p>";
// do stuffs
}
}
?>
I'm not 100% sure, but I think getting rid of the {} around the $username and $password should fix the issue, and yea, using LIKE for login is bad. I could then type %abijeet% in my username and %p% in the password field and get logged in as long as there is someone called abijeet in the system and has a password with the letter p in it.
Using PDO
Also, filtering the input from the $_POST is a good idea. In general, I'd ask you to drop using mysqli and look into PDO - http://php.net/manual/en/book.pdo.php
Using PDO properly with parameters will secure you against SQL Injection attacks.
Hashing the password
Don't store the password in plain test, hash it before saving. Check here - http://php.net/manual/en/function.password-hash.php
UPDATE -
OK, so as pointed out the {} are ok. Another thing that looks suspicious to me is the condition checking.
I would change it to this -
// Check the condition checking below!
if ($result->num_rows !== 1) {
echo "<p>Invalid username/password combination</p>";
} else {
echo "<p>Logged in successfully</p>";
// do stuffs
}
It could be an operator precedence issue and is anyways more confusing.

php login failure using AD LDS

i am trying to write a basic php script which connects to my AD LDS instance and authenticates a user, but i am getting login failure. the scripts are:
<?php
include("authenticate.php");
// check to see if user is logging out
if(isset($_GET['out'])) {
// destroy session
session_unset();
$_SESSION = array();
unset($_SESSION['user'],$_SESSION['access']);
session_destroy();
}
// check to see if login form has been submitted
if(isset($_POST['userLogin'])){
// run information through authenticator
if(authenticate($_POST['userLogin'],$_POST['userPassword']))
{
// authentication passed
header("Location: success.php");
die();
} else {
// authentication failed
$error = 1;
}
}
// output error to user
if (isset($error)) echo "Login failed: Incorrect user name, password, or rights<br /-->";
// output logout success
if (isset($_GET['out'])) echo "Logout successful";
?>
<form action="login.php" method="post">
User: <input type="text" name="userLogin" /><br />
Password: <input type="password" name="userPassword" />
<input type="submit" name="submit" value="Submit" />
</form>
the authenticate function is as follows:
for the ldap_dn and ldap_host, i have put in the values for the distinguised name of the active directory and the primary instance of AD LDS server respectively.
function authenticate($user, $password) {
// Active Directory server
$ldap_host = "server";
// Active Directory DN
$ldap_dn = "O=mycompany,C=US";
// connect to active directory
$ldap = ldap_connect($ldap_host);
// verify user and password
if($bind = #ldap_bind($ldap, $user, $password)) {
// valid
echo "<script>alert('valid');</script>";
// check presence in groups
$filter = "(userPrincipalName=" . $user . ")";
$attr = array("memberof");
$result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
$entries = ldap_get_entries($ldap, $result);
ldap_unbind($ldap);
if($result){
$_SESSION['user'] = $user;
return true;
}
else{
return false;
}
} else {
// invalid name or password
return false;
}
if($ldap)
return true;
else
return false;
}
i still get a login failure. am i setting the ldap host or the ldap_dn incorrectly? if yes, what values do i need to set?
As far as I know ldap_bind expects the given username to be a DN. And you are simply providing a username. I doubt that that works.
When I am doing LDAP-Logins, I always do a firt bind to get the DN from a username using either an anonymous bind or a dedicated user-account and as soon as there is the DN I use a second bind with the just retrieved DN and the provided password. That always works like a charm. And as I can define for myself which attributes I use in searching for the DN I can use whatever (unique) attriute there is to login.
I have created a little gist to show the basic concept.

Array Based Login - PHP

I wrote a script which verifies login detail based on array concept. It's not db based. Everything is working fine except one thing. Actually i have stored two login credentials in an array called $users.
If the user uses first login detail then login is always failed and prints message - "Wrong username or password" because the script matches the combination of each username and password with the incoming post data. And when user uses first credential, then the second credential gets failed and that's why we get "Wrong username or password". But if the user uses second login credential, then there is no problem and we get - "Login successful".
I know the reason why this is happening so, but couldn't resolve it yet. One common workaround could be to use header/redirection upon successful login so that wrong message for second login credentials dont appear.
But i want to print both the message according to login credential used - means successful login message should appear whether the user uses either first login credential or second one, and failed login message should appear if user doesn't use either of two login credentials. Here is my code -
<?php
$users = array();
$users["admin"] = "admin";
$users["test"] = 12345;
echo "<pre>";
print_r($users);
echo "</pre>";
if(isset($_POST['btnlogin']))
{
$uname = $_POST['txtuname'];
$pass = $_POST['txtpass'];
foreach($users as $username => $password)
{
if($username == $uname && $password == $pass)
{
$msg = "<p>Login successful</p>";
}
else
{
$msg = "<p>Wrong username or password</p>";
}
}
echo $msg;
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Array Based Login</title>
</head>
<body>
<form method="post" action="">
<input type="text" name="txtuname" /><br /><br />
<input type="password" name="txtpass" /><br /><br />
<input type="submit" name="btnlogin" value="Login" />
</form>
</body>
</html>
if(isset($_POST['btnlogin']))
{
$uname = $_POST['txtuname'];
$pass = $_POST['txtpass'];
foreach($users as $username => $password)
{
if($username == $uname && $password == $pass)
{
$msg = "<p>Login successful</p>";
//if success break the loop
break;
}
else
{
$msg = "<p>Wrong username or password</p>";
}
}
echo $msg;
}
$username=$_POST['username'];
$password=$_POST['password'];
if(isset($users[$username])&&$users[$username]['userPassword']==$password)
{
echo $_POST['username'];
}
else{
echo "not found";
}
the multidimensional array data can be accessed without using for loops check this out
this answer for the this is the question

Categories