Issue authenticating with LDAP - php

I'm trying to use IP.Board LDAP Login Handler; however, although the server connects and the query I perform is correct, I'm unable to login with a LDAP account. It throws the common "unknown username" error. The script connects successfully, because if I use wrong credentials it throws an authentication error in the LDAP settings page; this also happens if I force a ldap_search(): Search: Bad search filter or a ldap_search(): Search: Operations error when messing with the settings and trying to log in with an account in the Login Page. So the problem I believe should be somewhere else...
To test the settings I'm using, I have performed a successfully connection with the following code:
<?php
set_time_limit(30);
error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);
ini_set('display_errors',1);
// config
$ldapserver = 'server ip';
$ldapuser = 'username';
$ldappass = 'password';
$ldaptree = "OU=The,DC=path,DC=to,DC=users";
// connect
$ldapconn = ldap_connect($ldapserver) or die("Could not connect to LDAP server.");
if($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass) or die ("Error trying to bind: ".ldap_error($ldapconn));
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...<br /><br />";
$result = ldap_search($ldapconn,$ldaptree, "(cn=*)") or die ("Error in search query: ".ldap_error($ldapconn));
$data = ldap_get_entries($ldapconn, $result);
// SHOW ALL DATA
echo '<h1>Dump all data</h1><pre>';
print_r($data);
echo '</pre>';
// iterate over array and print data for each entry
echo '<h1>Show me the users</h1>';
for ($i=0; $i<$data["count"]; $i++) {
//echo "dn is: ". $data[$i]["dn"] ."<br />";
echo "User: ". $data[$i]["cn"][0] ."<br />";
if(isset($data[$i]["mail"][0])) {
echo "Email: ". $data[$i]["mail"][0] ."<br /><br />";
} else {
echo "Email: None<br /><br />";
}
}
// print number of entries found
echo "Number of entries found: " . ldap_count_entries($ldapconn, $result);
} else {
echo "LDAP bind failed...";
}
}
// all done? clean up
ldap_close($ldapconn);
?>
It renders the array completely, showing me the complete list of users belonging to that path and that should be enough for IPB to validate the information, isn't it?
Since the connection is actually successful but it doesn't locate an user, it doesn't generate any Log record about it.
I already checked the LDAP username's permissions exposed in this thread: https://serverfault.com/questions/167371/what-permissions-are-required-for-enumerating-users-groups-in-active-directory/167401 so the user has administrative rights and also can read those elements.
This is quite frustrating. Any advise?

I found the UID field required by IPB was CNin our LDAP setup. After correcting this small thing, I finally managed to perform the sync

Related

PHP ldap_get_entries() return count=zero

I am trying to authenticate users' login against LDAP(Server is Mac El Capitan).
I can successfully connect and bind to the ldap server.
I can search and sort the result.
But when I perform "ldap_get_entries",I received "Zero" entry.
I've tried everything from StackOverFlow to Google's second page.
Any Suggestions or idea why this might be happening?
MY CODE -
<?php
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
if (isset($_POST['submit'])) {
if (empty($_POST['email']) || empty($_POST['password'])) {
$error = "Username or Password is invalid";
}
else
{
$usernameLogin=$_POST['email'];
$passwordLogin=$_POST['password'];
$username = stripslashes($usernameLogin);
$password = stripslashes($passwordLogin);
echo "User name is ".$username;
echo "</br>";
$ldapUser = "uid=xxxxxx,cn=users,dc=dns1,dc=xxxxxxxx,dc=com";
$ldapPass = "xxxxxxxxxxx";
$url = "ldap://dns1.xxxxxxx.com:389";
$ldap = ldap_connect("$url") or die("Could not connect to LDAP server.");
$baseDN = "cn=users,dc=dns1,dc=xxxxxxxxx,dc=com";
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS,0);
$bind = ldap_bind($ldap, $ldapUser, $ldapPass);
if($bind) {
echo "Connected To LDAP";
echo "</br>";
$filter="(sAMAccountName=$username)";
echo "Filter = ".$filter;
echo "</br>";
$result = ldap_search($ldap,$baseDN,$filter) or die("Could not search.");
echo "Result = ".$result;
echo "</br>";
$sort = ldap_sort($ldap,$result,"uid");
echo "Sort = ".$sort;
echo "</br>";
$number = ldap_count_entries($ldap, $result);
echo "Count Entries = ".$number;
echo "</br>";
$info = ldap_get_entries($ldap, $result);
echo "Data for " . $info["count"] . " items returned:<p>";
echo "Info = ".$info;
echo "</br>";
echo '<pre>'; print_r($info); echo '</pre>';
echo "</br>";
$fentry= ldap_first_entry($ldap, $result);
echo "First Entry = ".$fentry;
for ($i=0; $i<$info["count"]; $i++)
{
if($info['count'] > 1)
break;
echo "<p>You are accessing <strong> ". $info[$i]["sn"][0] .", " . $info[$i]["givenname"][0] ."</strong><br /> (" . $info[$i]["samaccountname"][0] .")</p>\n";
echo '<pre>';
var_dump($info);
echo '</pre>';
$userDn = $info[$i]["distinguishedname"][0];
}
ldap_close($ldap);
}
else{
echo "Cannot Connect To LDAP.";
}
}}
?>
I can connect - bind - search But "ldap_get_entries()" returns zero.
First: You can skip the or die "Could not connect to LDAP Server" as that will almost never happen. ldap_connect only checks the parameter for syntactical correctness and does not actually connect to the server. The actual connection happens on the first call to the server which usually is ldap_bind. That's why conncetion issues often surface on ldap_bind and not on ldap_connect.
Second: Where did you get samAccountName from? That's a field that's usually used by ActiveDirectory. In Apples OpenDirectory the user is usually identified by the uid-attribute. So your filter should be sprintf('uid=%s', $username).
Third: I doubt that only Users in the group "Open Directory Administrators" are allowed to bind agains the LDAP. They for sure are the only ones allowed to edit the directory but every other user can bind as well.
Fourth: ldap_sort is deprecated by now. It's not sorting on the server side but on the client side. So only the returned results are sorted. When you have paged results that means that - even though you sorted the result - there still will be entries that would fit right in between your results. I'm currently working on a way to use server-sided sorting but that relies on the feature to be available on the server. So you can use ldap_sort but you can also implement your own sorting on the result set.
So change the filter to uid=$username and you'll get the expected results. The mail attribute might also contain the full email-address and might therefore then fail! You can also adapt the filter to search more than one field. Have a look at this slide for short examples.
Solved it. I used "mail" instead of "sAMAccountName".
Here's the details -
1 ) From
$filter="(sAMAccountName=$username)";
to
$filter="(mail=$username)";
2 ) From
$sort = ldap_sort($ldap,$result,"uid");
to
$sort = ldap_sort($ldap,$result,"mail");
That's it.
Lessons learn from here -
Use "LDAP Admin Tool" or some sort of LDAP Tool to understand the structure of your LDAP environment before jumping into coding. Big lesson learnt.

Ldap get dynamic values via PHP

so i had used php to connect to AD using LDAP and i had successfully retrieved the data using LDAP-PHP connection...
my ad is like...
my code is...
<?php
// config
$ldapserver = 'ad.univ3.edu';
$ldapuser = 'some';
$ldappass = 'some';
$ldaptree1 = "OU=TEST,OU=STUDENT,DC=ad,DC=univ3,DC=edu";
// connect
$ldapconn = ldap_connect($ldapserver) or die("Could not connect to LDAP server.");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
if($ldapconn){
echo "Connected to ".$ldapserver.'<br /><br />';
}
if($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass) or die ("Error trying to bind: ".ldap_error($ldapconn));
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...<br /><br />";
$result = ldap_search($ldapconn, $ldaptree1, "cn=*") or die ("Error in search query: ".ldap_error($ldapconn));
$data = ldap_get_entries($ldapconn, $result);
//SHOW ALL DATA
echo '<pre>';
print_r($data);
echo '</pre>';
$count = ldap_count_entries($ldapconn, $result);
// print number of entries found
echo "Number of entries found: " . $count;
} else {
echo "LDAP bind failed...";
}
}
// all done? clean up
ldap_close($ldapconn);
?>
i got details in print_r($data); but i get it in array...
i need like.. find all OU inside domain dynamically and get count in each OU(like users, computers, etc...) via specifying only domain..
i don't want to hardcode stuff like..
$ldaptree1 = "OU=TEST,OU=STUDENT,DC=ad,DC=univ3,DC=edu";
any ideas?? i can't get reference to do this as the information about LDAP is Generic...
Thanks in advance...

Active Directory integration with Wordpress and LDAP

I am implementing Wordpress authentication with Active Directory Credentials using LDAP. For this I have dedicated service account ‘user’. With this service account I am not able to getting complete user list which is required for authentication purpose. I am not sure but It could be the case of permissions with service account.
I am able to connect with AD with the service account but when I am trying to query for users, it returns nothing. I need whole user list from AD
// config
$ldapserver = 'My server';
$ldapport = 389;
$ldapuser = 'User';
$ldappass = 'password';
$ldaptree = "complete String";
// connect
$ldapconn = ldap_connect($ldapserver,$ldapport) or die("Could not connect to LDAP server.");if($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass) or die ("Error trying to bind: ".ldap_error($ldapconn));
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...<br /><br />";
$filter = "(&(&(&(objectCategory=person)(objectClass=user))))";
$result = ldap_search($ldapconn,$ldaptree, $filter) or die ("Error in search query: ".ldap_error($ldapconn));
$data = ldap_get_entries($ldapconn, $result);
// SHOW ALL DATA
echo '<h1>Dump all data</h1><pre>';
print_r($data);
echo '</pre>';
// iterate over array and print data for each entry
echo '<h1>Show me the users</h1>';
for ($i=0; $i<$data["count"]; $i++) {
//echo "dn is: ". $data[$i]["dn"] ."<br />";
echo "User: ". $data[$i]["cn"][0] ."<br />";
if(isset($data[$i]["mail"][0])) {
echo "Email: ". $data[$i]["mail"][0] ."<br /><br />";
} else {
echo "Email: None<br /><br />";
}
}
// print number of entries found
echo "Number of entries found: " . ldap_count_entries($ldapconn, $result);
} else {
echo "LDAP bind failed...";
}}// all done? clean up
ldap_close($ldapconn);
Here is a guide / code snippit for authenticating using PHP and active directory. If you are dead set on retrieving ALL users for some reason simply modify the filter, and then remove the break statement in the for loop.
http://www.exchangecore.com/blog/how-use-ldap-active-directory-authentication-php/

PHP LDAP, adding new entries into LDAP

I am wanting to create a form that I can fill out and once I submit it the form values can be pulled out and that person can be created into LDAP. I am not very experienced with LDAP infact I just worked towards making an LDAP bind work so I am needing some help. How can I add new users into LDAP through this form I can fill out? I know LDAP has an Add commands but I am not particularly sure on how to get started and what information needs to be passed for the person to be created in LDAP. If it helps, below is my code for LDAP bind.
<?php
$name=$_REQUEST['name'];
$x=1;
if($x==1)
{
//LDAP stuff here.
$username = "myusername";
$password = "mypass";
$ds = ldap_connect('ldap://ldap:389');
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
//Can't connect to LDAP.
if( !ds )
{
echo "Error in contacting the LDAP server -- contact ";
echo "technical services! (Debug 1)";
exit;
}
//Connection made -- bind anonymously and get dn for username.
$bind = #ldap_bind($ds);
//Check to make sure we're bound.
if( !bind )
{
echo "Anonymous bind to LDAP FAILED. Contact Tech Services! (Debug 2)";
exit;
}
$search = ldap_search($ds, "ou=People,DC=sde,DC=goliat,DC=com", "uid=$username");
//Make sure only ONE result was returned -- if not, they might've thrown a * into the username. Bad user!
if( ldap_count_entries($ds,$search) != 1 )
{
echo "Error processing username -- please try to login again. (Debug 3)";
redirect(_WEBROOT_ . "/try1b.php");
exit;
}
$info = ldap_get_entries($ds, $search);
//Now, try to rebind with their full dn and password.
$bind = #ldap_bind($ds, $info[0][dn], $password);
if( !$bind || !isset($bind))
{
echo "Login failed -- please try again. (Debug 4)";
redirect(_WEBROOT_ . "/try1b.php");
exit;
}
//Now verify the previous search using their credentials.
$search = ldap_search($ds, "ou=People,DC=sde,DC=goliat,DC=com", "cn=$name");
$info = ldap_get_entries($ds, $search);
if( $username == "myusername" )
{
/*
very useful set of information to view the LDAP tree info from an array
echo $username;
echo "<pre>".print_r($info[0],true)."</pre><br />";
*/
echo $info[0][cn][0];
echo ",";
echo $info[0][mail][0];
echo ",";
echo $info[0][telephonenumber][0];
exit;
}
else
{
echo "Error. Access Denied";
redirect(_WEBROOT_ . "/try1b.php");
exit;
}
ldap_close($ds);
exit;
}
?>
I would recommend a newUser.php (or whatever) file that checks to make sure that all of your required information is present, then send that info to the file you have started above.
Your $bind should take three variables...
$bind = ldap_bind($ds, 'cn=root,dc=example,dc=com', secretPassword);
For a pretty good guide to adding people to your LDAP server via PHP go to http://www.php2python.com/wiki/function.ldap-add/
Good luck
An add request requires the distinguished name to be added and the attribute that are to be part of the entry, and optional request controls.
On another subject, your search has subtree scope and may return more than one entry that matches user name. There is no reason why there could not be multiple entries with the same RDN in different branches underneath the base object specified in the code - unless your directory server vendor has implemented an attribute uniqueness constraint.

LDAP and PHP connection failure

I am trying to connect to a secure LDAP server (using LDAPs) via PHP, but I am having problems with it. I get the following error
Warning: ldap_bind() [function.ldap-bind]: Unable to bind to server: Can't contact LDAP server in /var/www/test.php on line 16
I works when I try to connect without LDAPs, but it is required that I use LDAPs because I am going to be dealing with sensitive information.
I am using the following code
<?php
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection
echo "<h3>LDAP query test</h3>";
echo "Connecting ...";
$ds=ldap_connect("ldaps://server"); // must be a valid LDAP server!
print $ds;
if ($ds) {
echo "<br><br>Binding ...";
$r=ldap_bind($ds); // this is an "anonymous" bind, typically
// read-only access
echo "Bind result is " . $r . "<br />";
echo "Searching for (sn=S*) ...";
// Search surname entry
$sr=ldap_search($ds, "ou=people,o=server.ca,o=server", "uid=username*");
echo "Search result is " . $sr . "<br />";
echo "Number of entires returned is " . ldap_count_entries($ds, $sr) . "<br />";
echo "Getting entries ...<p>";
$info = ldap_get_entries($ds, $sr);
echo "Data for " . $info["count"] . " items returned:<p>";
print_r($info);
// for ($i=0; $i<$info["count"]; $i++) {
// echo "dn is: " . $info[$i]["dn"] . "<br />";
// echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
// echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
// }
echo "Closing connection";
ldap_close($ds);
} else {
echo "<h4>Unable to connect to LDAP server</h4>";
}
?>
The problem is not related to the actual binding process (invalid credentials) as the warning would be a different one if the LDAP server could not authenticate your credentials. But as Paul Dixon noted the use of ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3) should be required - even though I don't think that this is the cause of your problems.
Which LDAP server type are you connecting to? OpenLDAP, Active Directory or something else?
What's the operating system of the computer running your PHP program?
Are you using a self-signed SSL certificate on the LDAP server and is the certificate authority for the given certificate trusted by the machine running your PHP program?
Which port does the LDAP server run on? 636 would be the "official" port for LDAPS. Perhaps you can add the port explicitly to the server address: ldaps://<<server>>:636.
ext/ldap has some issues with SSL/TLS secured connections. You can try to add
TLS_REQCERT never
to the ldap.conf (/etc/ldap.conf or /etc/ldap/ldap.conf on *nix-based systems) or for Windows machines create a ldap.conf with the above content in C:\OpenLDAP\sysconf\ldap.conf (the path must be an exact match as it's hard-coded into the extension).
It appears to be a problem using SSL/TLS on some servers with recent PHP versions. Not sure why. You can refer to my post at: Problems with secure bind to Active Directory using PHP
One of the more likely causes, is the cause from Stefan. To make sure that this is really the case, you can use:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
before your ldap_connect. This will print a more sane error message to log (typically ssl cert not valid, ref. Stefan Gehrig)
Although old, I have encountered the same issue and wanted to provide some insight for future readers.
Part of the problem was out-of-date OpenSSL libraries, 0.9.6 vs 1.0.0 (which worked).
After updating OpenSSL on the server, it was noted that PHP lost support for OpenSSL.
You can check support for modules with the following from the command line:
php -m
Or
echo phpinfo(INFO_MODULES);
From the browser.
Also, there have been a lot of issues with SSL Support for LDAP when using the OCI8/Oracle LDAP libs in my professional experience. On Debian platforms, Libldap-2.4.2-dev packages work best.
Additionally, you should look at the connection logs on the LDAP server. I can almost guarantee that you will see an error referring to SSLv3 and missing a CA for the certificate.
By default, PHP looks for the CA file on UNIX systems in, make sure it is readable by the PHP invoker (user via cli, Apache user, etc..):
/etc/pki/CA
This is not necessarily a PHP issue, but a configuration issue with Secure LDAP. Please see this PHP bug report and this OpenLDAP thread.
The OpenLDAP thread above has a snippet of a working OpenLDAP config for reference.
Some other things to check is your services definitions in /etc/services. Make sure you have the following:
ldaps 636/tcp # LDAP over SSL
ldaps 636/udp
I think you just need to set the ldap protocol version to be 3
echo "<h3>LDAP query test</h3>";
echo "Connecting ...";
$ldap_server = 'ldaps://server';
$ldap_port = '636';
$ds = ldap_connect($ldap_server, $ldap_port);
if ($ds)
{
//add this
if (!ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3))
{
fatal_error("Failed to set LDAP Protocol version to 3, TLS not supported.");
}
echo "<br><br>Binding ...";
$r=ldap_bind($ds); // this is an "anonymous" bind, typically
// read-only access
echo "Bind result is " . $r . "<br />";
echo "Searching for (sn=S*) ...";
// Search surname entry
$sr=ldap_search($ds, "ou=people,o=server.ca,o=server", "uid=username*");
echo "Search result is " . $sr . "<br />";
echo "Number of entires returned is " . ldap_count_entries($ds, $sr) . "<br />";
echo "Getting entries ...<p>";
$info = ldap_get_entries($ds, $sr);
echo "Data for " . $info["count"] . " items returned:<p>";
print_r($info);
// for ($i=0; $i<$info["count"]; $i++) {
// echo "dn is: " . $info[$i]["dn"] . "<br />";
// echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
// echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
// }
echo "Closing connection";
ldap_close($ds);
}
else
{
echo "<h4>Unable to connect to LDAP server</h4>";
}
On UNIX "man ldap.conf" = ... SYNOPSIS /usr/local/etc/openldap/ldap.conf ...
Write TLS_REQCERT never in /usr/local/etc/openldap/ldap.conf
and set ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
This work in my project on Nginx+PHP-fpm:
nginx/1.6.0
php55-5.5.15
php55-ldap-5.5.15
openldap-client-2.4.39_1
What saved my day after reading and trying out solutions from allover the web and SO, was to use a ldaps uri without the port specified in it.
So instead of this: ldaps://example.com:636 I had to use this: ldaps://example.com and it now works like a charm.
I was setting this up on Ubuntu 16.04 with PHP7.3 runing through Nginx and php-fpm.
A full code example:
try{
$ldapUri = "ldaps://example.com";
$ldapUsername = 'username';
$ldapPassword = 'password';
$ldapConn = ldap_connect($ldapUri);
if($ldapConn){
ldap_set_option($ldapConn,LDAP_OPT_NETWORK_TIMEOUT,10);
if(!ldap_set_option($ldapConn,LDAP_OPT_PROTOCOL_VERSION,3)){
print 'Failed to set ldap protocol to version 3<br>';
}
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS,0);
$ldapBind = ldap_bind($ldapConn, $ldapUsername, $ldapPass);
if ($ldapBind) {
echo "LDAP bind successful...";
//DO LDAP search and stuff
ldap_unbind($ldapConn);
} else {
echo "LDAP bind failed...";
}
}
}catch(Exception $e){
print($e->getMessage();
}
Try to enable "anonymous binds" on your LDAP-Server or use a correct bind (username / password).
like cn=ldapauthuser,ou=accounts,dc=example,dc=com

Categories