I am trying to do an ldap authorization and then a secondary check for membership in a group. System is an Ubuntu machine running php 5.3.10 authenticating against a Server2008 R2 Active Directory. I can't seem to get ldap_search() to work. I have pulled the DN from jExplore so I am pretty sure the DN is correct. ldap_bind works (in another function) with the credentials so I am sure the server and the username/password are valid. The error:
PHP Warning: ldap_search(): Search: Operations error in /var/www/zzz.php on line 28
The code:
$ldap = ldap_connect('ldap://xxx.xxx');
$admins = $auth['admin'];
// User not logged in, user level '0'
if (!isset($user))
{
return 0;
}
// DN
$group_dn = 'CN=IT Employees,OU=groups,OU=users,OU=xxx,DC=xxx,DC=xxx';
// Filter
$filter = '(sAMAccountName=' . $user . ')';
// Attributes
$attr = array("memberof","givenname");
echo $group_dn.' '.$filter.' '.$attr.'<br />';
// Check if the user is a member of the Admin Group
$SubGroups = ldap_search($ldap, $group_dn, $filter, $attr); //Search the admin group for user.
$debug = ldap_get_entries($ldap, $SubGroups);
echo $debug['count'];
if ($debug['count']>>0)
{
// Yep, you are set admin. (User level 2)
echo "Admin Set<br />";
return 2;
}
else
{
// Failure. Thou art a normal user. (User level 1)
echo "Admin Denied<br />";
return 1;
}
}
$ldap = ldap_connect('ldap://xxx.xxx');
needed to change to
$ldap = ldap_connect('ldap://xxx.xxx');
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_start_tls($ldap);
$bind= ldap_bind($ldap, 'user','pass');
I think this filter should work:
(&(objectClass=user)(sAMAccountName=yourUserName)
(memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))
Well I am sure this could be tuned to work for you.
-jim
Related
I'm trying to add the user to my LDAP server. But I'm getting the below error.
PHP Warning: ldap_add(): Add: Referral
Code:
$ds = ldap_connect("HOST","PORT");
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($ds, "adminusername", "Passwrd");
echo $bind;
// prepare data
$base_dn = 'CN=Manus Test,OU=UserAccounts,DC=rk.com,DC=rk';
$info["givenName"]="manu";
$info["sn"]="Manu";
$info["uid"]="manus";
$info["homeDirectory"]="/home/";
$info["mail"]="manus#gmail.com";
$info["displayName"]= "Jdkd sjs";
$info["cn"] ="Manus Test";
//$info["userPassword"]=>user_hash;
$info["objectclass"][0] = "top";
$info["objectclass"][1] = "person";
$info["objectclass"][2] = "inetOrgPerson";
$info["objectclass"][3] = "organizationalPerson";
// add data to directory
$r = ldap_add($ds, $base_dn, $info);
echo "Bind result is " . $r . "<br />";
Please let me know any suggestions.
Referrals can be returned if you are talking to a slave LDAP server (essentially a read-only copy of the directory). If you know you are talking to a server hosting a writable copy of the replica, referrals are also returned when the DN base is not something hosted by that server.
Looking at the code above, "DC=rk.com,DC=rk" is unusual. I generally see the "domain" components broken out so rk.com becomes "dc=rk,dc=com". Use an ldap browser to verify the pattern for fully qualified DNs in your directory.
Firstly, Id like to state that my PHP/LDAP skillset is minimal so am looking for a sudo genius to help me solve this issue.
Having recently merged with another company, the business wants us to allow our users to authenticate against a PHP web application in another Active Directory domain that we have a forest trust with.
Below is the code I've been given for the LDAP connection and the previous person who was a PHP genius has now left the company and this has been lumped onto me to work out. The code is however not working. The users in domain where the PHP application is store are able to access correctly.
<?php
$browser_shortname = explode('\\', $_SERVER['AUTH_USER']);
// Generate the global LDAP connection to the specificed primary server.
$ldap_connection = ldap_connect($ldap_protocol.$ldap_primaryhost) or die( header('Location: /error/?e=LD01'));
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, $ldap_protocolversion);
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, $ldap_referrals);
if ($ldap_tls == 1) {
ldap_start_tls($ldap_connection);
}
if ($ldap_debug == 1) {
ldap_set_option($ldap_connection, LDAP_OPT_DEBUG_LEVEL, 7);
}
$ldap_binding = ldap_bind($ldap_connection, $ldap_domain.'\\'.$ldap_username, $ldap_password);
if (!$ldap_binding) {
include ('/core/styles/'.$theme_selected.'/templates/101.tpl');
die();
}
$ldapus_filter = "(sAMAccountName=$browser_shortname[1])";
$ldapus_result = ldap_search($ldap_connection, $ldap_dn, $ldapus_filter);
$ldapus_details = ldap_get_entries($ldap_connection, $ldapus_result);
if ($browser_shortname[0] == "MY-DOMAIN") {
$ldap_khaconnection = ldap_connect($ldap_protocol.$ldap_khahost) or die( header('Location: /error/?e=LD01'));
ldap_set_option($ldap_khaconnection, LDAP_OPT_PROTOCOL_VERSION, $ldap_protocolversion);
ldap_set_option($ldap_khaconnection, LDAP_OPT_REFERRALS, $ldap_referrals);
$ldapus_filter = "(sAMAccountName=$browser_shortname[1])";
$ldapus_result = ldap_search($ldap_khaconnection, $ldap_khadn, $ldapus_filter);
$ldapus_details = ldap_get_entries($ldap_khaconnection, $ldapus_result);
echo "This confirms the user is coming from KHA.";
echo $browser_shortname[1];
}
$ldap_userfullname = $ldapus_details[0]["displayname"][0];
$ldap_userfirstname = $ldapus_details[0]["givenname"][0];
$ldap_usertitle = $ldapus_details[0]["title"][0];
$ldap_accountname = $ldapus_details[0]["samaccountname"][0];
?>
I am integrating my login form with Microsoft active directory. I authenticate
users via LDAP php library.
When user try to log in, they enter username & password.
Connecting to server go successfully, authentication via "LDAP_bind" also
give me true or false according to the values correctness.
Now i am not able to retrieve the user Real name to display it on the screen.
ALL Information I have are the ldap uri with the port number, and username & password entered via the webform.
here is my current code,
$ldap = ldap_connect("ldap://abc.xyz:123");
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'#abc.xyz',$_REQUEST['password']))
{ echo "Welcome". $_REQUEST['username'];}
the $_REQUEST['username'] is not human readable, so i need to read this user attributes or at least display name only.
ldap_search and ldap_read functions did not help, I tried this code:
$ldap_base_dn = 'DC=abc,DC=xyz';
$search_filter = "(objectclass=*)";
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);
with no luck, is there any other information i must have in order to make the ldap_search or ldap_read work successfully. in other words can this be done by having the username and password and the ldap uri only?
You should be able to do the search like this:
$upn = $_REQUEST['username'].'#abc.xyz';
$attributes = ['displayname'];
$filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($upn, null, LDAP_ESCAPE_FILTER)."))";
$baseDn = "DC=abc,DC=xyz";
$results = ldap_search($ldap, $baseDn, $filter, $attributes);
$info = ldap_get_entries($ldap, $results);
// This is what you're looking for...
var_dump($info[0]['displayname'][0]);
Also, make sure to do the bind with these options:
$ldap = ldap_connect("ldap://abc.xyz:123");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'#abc.xyz',$_REQUEST['password']))
When returning the DisplayName value, I recommend that you use a search filter which looks for the samaccountname (username) using something as simple as (samaccountname=$u) with $u being the username from your LDAP connect. If your Active Directory/Open Directory has a lot of objects, I would most certainly recommend targeting OU's as this query can fall on it's bottom pretty quickly.
I've made some further changes to your code so it now runs inside a function which takes 3x params and returns false if the connection or authentication fails.
Check LDAP - Return DisplayName if success login or FALSE(BOOL) if fail login or connection.
function chkLDAP($u, $pass, $domain) {
$dom = "$domain\\"; //Domain Prefix for UNAME which ouputs "domain\"
$user = $dom . $u;
$hostname = 'ldap://abc.com';
$baseDN = 'OU=users, DC=abc, DC=com'; //Narrow down if you have alot of objects as search could take along time
$search = "(samaccountname=$u)"; //Compare with Username
$ldap = ldap_connect($hostname);
if ($ldap) {
$ldapbind = ldap_bind($ldap, $user, $pass);
if ($ldapbind) {
$ldapSearch = ldap_search($ldap, $baseDN, $search);
$entry = ldap_first_entry($ldap, $ldapSearch);
$info = ldap_get_values($ldap, $entry, "displayname");
return $info[0];
}
return false; //Failed Auth
}
return false; //Connection Failed
}
Just test the function for false to make sure you have a displayname before using it.
Run Function:
$displayName = chkLDAP($_REQUEST['username'], $_REQUEST['password'], 'abc.com'); //Run Function - Returns False if Failed or Displayname if True
if ($displayName !== false) {
echo $displayName;
} else {
echo "Username or Password Incorrect!";
}
See:
http://php.net/manual/en/function.ldap-get-values.php
This worked for me for people who need to validate if a user exists in a specific OU.
(by the help of #kitson88 response)
function validateLogin($username,$password)
{
$ldap_dn = "$username#alhait.com";
$ldap_password =$password;
$ldap_con = ldap_connect("server");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if(#ldap_bind($ldap_con,$ldap_dn,$ldap_password))
{
$baseDN = 'OU=trainers,DC=alhait,DC=com';
$search = "(samaccountname=$username)";
$ldapSearch = ldap_search($ldap_con, $baseDN, $search);
$entry = ldap_first_entry($ldap_con, $ldapSearch);
$info = ldap_get_values($ldap_con, $entry, "displayname");
// var_dump($info[0]);
if($info[0]!=null)
{
return true;
}
}else{
return false;
}
//echo "Invalid Credential";
return false;
}
I know this has sort of been answered before but it hasnt been able to help me (unless it has but because of my limited php knowledge it hasn't helped). Here is my code below:
<body>
<html>
<?php
//echo var_dump($_POST);
$user = "".$_POST["username"]."";
settype($user, "string");
$password = $_POST["password"];
$ldap_host = "ldap.burnside.school.nz";
$base_dn = "ou=students,o=bhs";
$ldap_user = "(cn=".$user.")";
$filter = "($ldap_user)"; // Just results for this user
$ldap_pass = "".$password."";
$connect = ldap_connect($ldap_host)
or exit(">>Could not connect to LDAP server<<");
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
// This next bit is the important step. Bind, or fail to bind. This tests the username/password.
if (ldap_bind($connect, $ldap_user.",".$base_dn, $ldap_pass)) {
$read = ldap_search($connect, $base_dn, $filter)
or exit(">>Unable to search ldap server<<");
// All the next 8 lines do is get the users first name. Not required
$info = ldap_get_entries($connect, $read);
$ii = 0;
for ($i = 0; $ii < $info[$i]["count"]; $ii++) {
$data = $info[$i][$ii];
if ($data == "givenname") {
$name = $info[$i][$data][0];
}
}
ldap_close($connect);
header("Location: success.php?name=$name");
}
else {
ldap_close($connect);
//header("Location: failure.php?user=$user");
}
?>
</body>
</html>
I am getting an error on line 21 which is when I bind to the server saying:
Warning: ldap_bind(): Unable to bind to server: Invalid DN syntax in S:\XAMPP\htdocs\PhpProject1\LDAP_main.php on line 21
Would anyone have a solution to this problem? It has only started happening when I implemented my $_POST into the code to receive the username and password but as you can see with my commented out // echo var_dump($_POST) I am actually receiving the data I want.
Your DN for binding to the LDAP-Server is (cn=[username]),ou=students,o=bhs which is not a valid DN-Syntax. That should read cn=[username],ou=students,o=bhs without the braces.
You have mixed up an LDAP-Filter (the stuff inside the braces) with a DN.
I'd do an LDAP authentication in the following way:
Bind anonymously or with a default user where you know the DN
Use that user to do a search for all users that match a certain filter that contains the provided username. you can use a filter like (|(mail=[username])(cn=[username])(uid=[username])) to look for entries that have the username in the mail, cn or uid-attribute
Get the DN from the returned Entry (if there are no or more than one entry there is no appropriate user existent so we can skip the rest)
bind to the ldap again with that retreived DN and the provided password.
Have a look at https://gist.github.com/heiglandreas/5689592
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.