Authenticating user with LDAP from PHP with only SamAccountName and Password? - php

how can I authenticate from PHP using LDAP when I only have the SamAccountName and Password? Is there a way to bind with just SamAccountName and Password and without Distinguished Name. The only examples I have found assume you have the DN:
$server="XXX.XXX.XXX.XXX";
$dn = "cn=$username, ";
$basedn="ou=users, ou=accounts, dc=domain, dc=com";
if (!($connect = ldap_connect($server))) {
die ("Could not connect to LDAP server");
}
if (!($bind = ldap_bind($connect, "$dn" . "$basedn", $password))) {
die ("Could not bind to $dn");
}
$sr = ldap_search($connect, $basedn,"$filter");
$info = ldap_get_entries($connect, $sr);
$fullname=$info[0]["displayname"][0];
$fqdn=$info[0]["dn"];

This works for me. I spent many a days trying to figure this one out.
<?php
//We just need six varaiables here
$baseDN = 'CN=Users,DC=domain,DC=local';
$adminDN = "YourAdminDN";//this is the admin distinguishedName
$adminPswd = "YourAdminPass";
$username = 'Username';//this is the user samaccountname
$userpass = 'UserPass';
$ldap_conn = ldap_connect('ldaps://yourADdomain.local');//I'm using LDAPS here
if (! $ldap_conn) {
echo ("<p style='color: red;'>Couldn't connect to LDAP service</p>");
}
else {
echo ("<p style='color: green;'>Connection to LDAP service successful!</p>");
}
//The first step is to bind the administrator so that we can search user info
$ldapBindAdmin = ldap_bind($ldap_conn, $adminDN, $adminPswd);
if ($ldapBindAdmin){
echo ("<p style='color: green;'>Admin binding and authentication successful!!!</p>");
$filter = '(sAMAccountName='.$username.')';
$attributes = array("name", "telephonenumber", "mail", "samaccountname");
$result = ldap_search($ldap_conn, $baseDN, $filter, $attributes);
$entries = ldap_get_entries($ldap_conn, $result);
$userDN = $entries[0]["name"][0];
echo ('<p style="color:green;">I have the user DN: '.$userDN.'</p>');
//Okay, we're in! But now we need bind the user now that we have the user's DN
$ldapBindUser = ldap_bind($ldap_conn, $userDN, $userpass);
if($ldapBindUser){
echo ("<p style='color: green;'>User binding and authentication successful!!!</p>");
ldap_unbind($ldap_conn); // Clean up after ourselves.
} else {
echo ("<p style='color: red;'>There was a problem binding the user to LDAP :(</p>");
}
} else {
echo ("<p style='color: red;'>There was a problem binding the admin to LDAP :(</p>");
}
?>

Actually, the answer is that it depends on how the LDAP server was configured by the admin. You don't always need a DN to authenticate to an LDAP server. In my particular case, even with the DN, I still couldn't authenticate to the LDAP server. For the LDAP server I was trying to connect, it appears it was a Microsoft Domain, and so I could only authenticate with DOMAIN\user015 for user015 in DOMAIN where user015 is a SamAccountName and DOMAIN is the domain for that user. But I was able to authenticate.
Thank you for all the posts! Even if they weren't the correct answer, they did help a lot!

Try user#domain on dn... It worked for me!

You always need a DN to authenticate to a LDAP server. After that, you can perform a filter based in a specific attribute, like SamAccountName, but you need an LDAP user identified by a DN.

The LDAP interface to AD requires that you bind using a DN. In order to authenticate a user, you must first find that user's DN — fortunately, you can find the DN by searching LDAP.
If you configure AD to allow anonymous queries (don't do this unless you are sure you're ok with the reduction in security), you can do
ldap_bind($connect, "", "")
$sr = ldap_search($connect, $base_dn, "(sAMAccountName=$username)")
And then retrieve that user's DN and proceed to rebind with the user's DN and password.
If you do not enable anonymous bind, then you use an application ID to do the initial search, like so:
ldap_bind($connect, "DN=LDAP_App,OU=Users,DC=Domain,DC=com", "thePassword")
$sr = ldap_search($connect, $base_dn, "(sAMAccountName=$username)")
And then, just as above, retrieve that user's DN and proceed to rebind.

Related

PHP - LDAP Authentication and Search

I am using an Online LDAP Test Server here: http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/ to test some basic LDAP code.
I need to authenticate a user and retrieve some user information.
If I understand the information about the test server correctly I should be able to bind with users that belong to respective groups. With the code 'AS IS' below I can bind to un-commented $dn, but if I use any other $dn to authenticate, the bind fails.
What am I not understanding?
For example, tesla should belong to 'ou=scientists,dc=example,dc=com' but I am unable to authenticate tesla on that DN and subsequently I can't search for related information.
$dn = 'dc=example,dc=com';
// $dn = 'ou=mathematicians,dc=example,dc=com';
// $dn = 'ou=scientists,dc=example,dc=com';
$username = 'tesla';
$password = 'password';
$filter = "(uid=" . $username . ")";
$ldapDN = 'uid=' . $username . ',' . $dn;
$ldapCONN = ldap_connect("ldap.forumsys.com") or die("Could not connect to LDAP server.");
if ($ldapCONN)
{
ldap_set_option($ldapCONN, LDAP_OPT_PROTOCOL_VERSION, 3);
$ldapBIND = #ldap_bind($ldapCONN, $ldapDN, $password);
if ( $ldapBIND )
{
$result = ldap_search($ldapCONN, $dn, $filter) or die ("Error: ".ldap_error($ldapCONN));
$data = ldap_get_entries($ldapCONN, $result);
echo '<pre>';
print_r($data);
echo '</pre>';
}
else
{
echo "LDAP bind failed...";
}
}
When using LDAP, it is important to visualize how the database is organized.
Basically, all users are in the main folder. Use this folder to authenticate your user with, otherwise it will not work.
In this case the main folder where all users are in, is dc=example,dc=com. However, most LDAP servers use a main folder like cn=users,dc=example,dc=com.
Why are they using folders at all then? Well, that is to make it easier to categorize and search with a filter. For example, if you want to only show the names of scientists, you add the group Scientists to your search filter like $filter = "(ou=Scientists)". A filter for both groups would look like this: $filter = "(&(ou=Scientists)(ou=Mathematicians)". Now the server will take a look into this folder/these folders, and display just these members.
Hope this helps, for gaining further insight in how the server is organized, I can recommend installing Apache Directory Studio. It is free to download from their site, helped me a lot!

Resetting a LDAP user's password in PHP, without the old password, using admin user

I am trying to figure out how to reset a LDAP user password when connected as another user (admin user) in PHP for a password reset feature.
$this->con = ldap_connect($this->server);
ldap_set_option($this->con, LDAP_OPT_PROTOCOL_VERSION, 3);
$user_search = ldap_search($this->con, $this->dn,"(|(uid=$user)(mail=$user))");
$this->user_get = ldap_get_entries($this->con, $user_search);
$user_entry = ldap_first_entry($this->con, $user_search);
$this->user_dn = ldap_get_dn($this->con, $user_entry);
$this->user_id = $this->user_get[0]["uid"][0];
$entry = array();
$entry["userPassword"] = "$encoded_newPassword";
ldap_modify($this->con, $this->user_dn, $entry)
(aggregated from class methods) This works for resetting a user's password using the old password, but how would you go about doing a password change with another user (admin in this case)?
I think there is something about the LDAP authentication/binding that I am not understanding. Perhaps someone can point me in the right direction.
can I do a ldap_bind before the ldap_modify that will allow me to use user_dn and update the user as the admin user?
Not clear on how this all works.
OpenLDAP is the implementation being used.
You can call ldap_bind with the dn/password of your admin user to establish the connection as this (admin) user.
Sample from the PHP manual
// using ldap bind
$ldaprdn = 'uname'; // ldap rdn or dn
$ldappass = 'password'; // associated password
// connect to ldap server
$ldapconn = ldap_connect("ldap.example.com")
or die("Could not connect to LDAP server.");
if ($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...";
} else {
echo "LDAP bind failed...";
}
}

PHP ldap_list() Bad search filter

I'm trying to list my Active Directory users using PHP ldap_list() function. I get the following errors when I execute the php code.
LDAP bind successful... Warning: ldap_list(): Search: Bad search filter in /var/www/html/ldapn.php on line 29
Below is my PHP Code:
<?php
// using ldap bind
$ldaprdn = 'draven#myserver.com'; // ldap rdn or dn
$ldappass = 'draven678'; // associated password
// connect to ldap server
$ldapconn = ldap_connect("dc.myserver.com")
or die("Could not connect to LDAP server.");
if ($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...";
} else {
echo "LDAP bind failed...";
}
$basedn = "dc=myserver, dc=com";
$justthese = array("OU_Test");
$sr = ldap_list($ldapconn, $basedn, "OU_Test=*", $justthese);
}
?>
note : OU_Test is an Organizational unit. My requirement is to list all users in that Organizational Unit.
What's wrong with my code? How will I be able to resolve this error?
To list all users in the Organizational Unit 'OU_TEST' with ldap_list() :
Use the appropriate $basedn. It should be the distinguished name of 'OU_TEST' since you want to list users that are INSIDE OU_TEST. You can get it with ldap_search().
Use the appropriate filter : to list only users, filter by users.
// 1. Get OU_TEST's dn. Search down the tree using a top/root dn as $basedn :
$basedn = "dc=myserver, dc=com";
// Filters usually looks like ([attributeName]=[attributeValue])
$filter = '(ou=OU_TEST)';
$sr = ldap_search($ds, $basedn, $filter);
... say we put the resulting dn in $OU_TEST_dn variable...
// 2. List users. If users are missing, use 'objectClass=organizationalPerson'
$filter = '(objectClass=Users)';
// Use the correct basedn
$basedn = $OU_TEST_dn;
// This should work
$sr = ldap_list($ldapconn, $basedn, $filter);
the filter here should be in braces:
here is how:
$sr = ldap_list($ldapconn, $basedn, "(OU_Test=*)", $justthese);
This should work just fine.
If it doesn't work
follow the example here
<?php
$ldapconfig['host'] = '10.10.10.10';
$ldapconfig['port'] = NULL;
$ldapconfig['basedn'] = 'dc=company,dc=com';
$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);
$dn="uid=".$username.",ou=OU_TEST,".$ldapconfig['basedn'];
if ($bind=ldap_bind($ds, $dn, $password)) {
echo("Login correct");
} else {
echo("Unable to bind to server.</br>");
echo("msg:'".ldap_error($ds)."'</br>"); //check if the message isn't: Can't contact LDAP server :)
//if it say something about a cn or user then you are trying with the wrong $dn pattern i found this by looking at OpenLDAP source code :)
//we can figure out the right pattern by searching the user tree
//remember to turn on the anonymous search on the ldap server
if ($bind=ldap_bind($ds)) {
$filter = "(OU_TEST=*)";
if (!($search=#ldap_search($ds, $ldapconfig['basedn'], $filter))) {
echo("Unable to search ldap server<br>");
echo("msg:'".ldap_error($ds)."'</br>"); //check the message again
} else {
$number_returned = ldap_count_entries($ds,$search);
$info = ldap_get_entries($ds, $search);
echo "The number of entries returned is ". $number_returned."<p>";
for ($i=0; $i<$info["count"]; $i++) {
var_dump($info[$i]); //look for your user account in this pile of junk and apply the whole pattern where you build $dn to match exactly the ldap tree entry
}
}
} else {
echo("Unable to bind anonymously<br>");
echo("msg:".ldap_error($ds)."<br>");
}
}
?>
Let me know if it does not work. We will try and figure it out!

PHP ldap bind issue

I've been looking at a couple of guides (and the PHP manual) trying to validate AD users on an intranet site I'm about to make. This is the first time I've used ldap_connect, and I haven't had the best of luck.
Could anyone look at my code and see what I'm missing?
Thanks.
<?php
$user = "08jf1";
$password = "pass";
// Active Directory server
$ldap_host = "10.43.48.5";
// Active Directory DN
$ldap_dn = "OU=CSE-W7,OU=Students-W7,DC=server,DC=local";
// Domain, for purposes of constructing $user
$ldap_usr_domain = "#server.local";
// Connect to AD host
$ldapconn = ldap_connect("10.43.48.5");
if ($ldapconn) {
$bind = ldap_bind($ldap_host, $ldap_dn, $user . $ldap_usr_domain, $password);
if ($bind) {
echo "Verified user";
//$_SESSION['username'] = $session_username;
//$_SESSION['password'] = $session_password;
} else {
echo "User does not exist";
}
}
?>
Edit: I can confirm ldap is enabled though phpinfo!
Is that syntax of ldap_bind correct?. Isn't it ldap_bind($ldapconn,$rdn,$password) ?
Binding may need a elevated privilege or authbind wrapper. Refer to authbind for ldap. LDAP AuthBind
Take a look at this very simple example: How to use LDAP Active Directory Authentication with 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.

Categories