This is my setting:
$base_dn = 'OU=Users,OU=MYCOMPANY_COM,DC=MYCOMPANY,DC=LOCAL';
$ldap_postfix = '#MYCOMPANY.LOCAL';
ldap_set_option($this->conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($this->conn, LDAP_OPT_REFERRALS, 0);
$search_filter = '(&(objectCategory=*)(objectClass=*)(SAMAccountName=' . $username . '*))';
Mu ldap is on Microsoft ActiveDirectory.
It works well and I get all parameters of requested username from ldap except info about department.
What am I dooing wrong?
After some investigation I found the problem.
It was due at AD was department empty. After this attribute was filled ldap return it.
Simple and stupid.
Related
What I got.
I got a simple HTML login form, where username and password are passed to an ldap.php. I am able to successfully login, as soon as I use cn= instead of sAMAccountName=as a parameter. For Example, the user Mickey Mouse and mmouse as login does not work. Instead I need to login with Mouse \, Mickey. Which is pretty uncomfortable.
Do I need to authenticate, with an privilege account first and perform another bind with the wanted user afterwards?
Whats the problem?
If I replace cn= with sAMAccountName= I run into an ldap_bind error.
<?php
// LDAP Bind parameters
$ldap_dn = "sAMAccountName=".$_POST["username"].",OU=User of myCompany,OU=myCompany,DC=myDomain,DC=com";
$ldap_password = $_POST["password"];
$ldap_connection = ldap_connect("myCompany.com");
// Set LDAP protocol version
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3);
// Set LDAP returns to 0
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0);
if (ldap_bind($ldap_connection, $ldap_dn, $ldap_password))
echo "Anmeldung erfolgreich";
else
echo "Anmeldung fehlgeschlagen";
?>
I'm creating an intranet PHP website without any login requirements. I have an IIS application (based on PHP), authentication is done with Windows Authentication (Anonymous Authentication is disabled). I've successfully managed to set up IIS and windows authentication with some GPO tweaks. My simple PHP page contains $_SERVER['REMOTE_USER']; so active directory user without any login prompts can see DOMAIN\User.Name
In my understanding IIS Windows authentication is very limited and can only display the user's name and domain name. So I enabled LDAP to display more information about the user such as display name or phone number. But I'm stuck here because as far as I know, LDAP uses username and password bind to retrieve information. When I use active directory admin credentials it gives me a table of all user's information but how to filter that table to display only current user information (based on windows authentication).
Code:
<?php
$current_user = get_current_user();
$ldap_password = 'AdminPassword';
$ldap_username = 'Administrator#domain.name';
$ldap_connection = ldap_connect("domain.name");
if (FALSE === $ldap_connection){
echo 'ERROR';
}
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0);
if (TRUE === ldap_bind($ldap_connection, $ldap_username, $ldap_password)){
$ldap_base_dn = 'OU=Users,DC=domain,DC=name';
$search_filter = '(|(objectCategory=person)(objectCategory=contact))';
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);
if (FALSE !== $result){
$entries = ldap_get_entries($ldap_connection, $result);
echo '<h2>Result</h2></br>';
echo '<table border = "1"><tr><td>Username</td><td>Last Name</td><td>First Name</td></tr>';
for ($x=0; $x<$entries['count']; $x++){
$LDAP_samaccountname = "";
if (!empty($entries[$x]['samaccountname'][0])) {
$LDAP_samaccountname = $entries[$x]['samaccountname'][0];
if ($LDAP_samaccountname == "NULL"){
$LDAP_samaccountname= "";
}
} else {
$LDAP_uSNCreated = $entries[$x]['usncreated'][0];
$LDAP_samaccountname= "CONTACT_" . $LDAP_uSNCreated;
}
//Last Name
$LDAP_LastName = "";
if (!empty($entries[$x]['sn'][0])) {
$LDAP_LastName = $entries[$x]['sn'][0];
if ($LDAP_LastName == "NULL"){
$LDAP_LastName = "";
}
}
//First Name
$LDAP_FirstName = "";
if (!empty($entries[$x]['givenname'][0])) {
$LDAP_FirstName = $entries[$x]['givenname'][0];
if ($LDAP_FirstName == "NULL"){
$LDAP_FirstName = "";
}
}
echo "<tr><td><strong>" . $LDAP_samaccountname ."</strong></td><td>" .$LDAP_LastName."</td><td>".$LDAP_FirstName."</td></tr>";
}
}
ldap_unbind($ldap_connection);
echo("</table>");
}
?>
EDIT: Managed to filter current user by editing LDAP filter:
$search_filter = "(|(objectCategory=persons)(sAMAccountName=*$current_user*))";
Your query is almost right, but it's working in a roundabout way :)
There is no objectCategory called persons. It's just person (no "s"). So objectCategory=persons is always false for every object on your domain. But it's working because you're using an OR (|).
So the only criteria it's really using is sAMAccountName=*$current_user*. But that's asking for any object where sAMAccountName contains $current_user. That has two unintended consequences:
If you have a user called neil, and another called oneil, then whenever neil logs in, you will find both accounts in that search.
Because your search criteria starts with a wildcard (*), it cannot use the index to find the account. That means that it has to look through every object on your domain to find a match. That might not matter if you have a small domain, but the more objects you have on your domain, the longer it will take.
IIS is giving you the exact username, so there is no need to make a "contains" comparison. So your query can be simplified to:
(sAMAccountName=$current_user)
Since sAMAccountName is an indexed attribute, that will be a super fast query.
You will often see the added criteria of limiting the search to user accounts, like this (notice the &):
(&(objectClass=user)(objectCategory=person)(sAMAccountName=$current_user))
But really, only users can authenticate to IIS, and the sAMAccountName is unique across all object types, so it doesn't really matter.
Im working on adding authentication to one of my dashboards.
My setup is a little unique I believe. We use a service account to obtain the DN of a user, this query works as expected. We then bind a second time using that new dn instead of the service account. This also works, so technically at this point, the user is properly authenticated.
I'm trying to perform a second ldap_search after succesful bind as the dn I pull from the first query. This is unfortunately giving me the results of the previous ldap_search. This is what I'm not understanding.
if($bind = #ldap_bind($ldap, $ldap_dn, $adminpass)) {
// valid
echo "bound to ldap<BR>\n";
$filter = "(&(objectclass=user)(samaccountname=$user))";
$attr = array("dn, password, samaccountname");
$dn = "DC=CORP,DC=COMPANY,DC=com";
$result = ldap_search($ldap, $dn, $filter, $attr) or exit("Unable to search LDAP server");
$entries = ldap_get_entries($ldap, $result);
// Now build second query to bind and authenticate as user.
$ldap_dn_bind = $entries["0"]["dn"];
echo $ldap_dn_bind;
if($ubind = #ldap_bind($ldap, $ldap_dn_bind, $password)) {
echo "bound as $user - $ldap_dn_bind<BR>\n\n"; // Works
$u_attr = array("description, physicaldeliveryofficename, postaladdress, st, postalcode, title, telephonenumber, mobile, samaccountname, givenname, sn, company, displayname, employeetype, mail, manager, employeeID, KMADescription, terminationdate");
$u_result = ldap_search($ldap, $dn, $filter, $u_attr) or exit("Unable to search LDAP server");
echo "ldap search<BR>\n";
$u_entries = ldap_get_entries($ldap, $u_result);
echo "print u_entries";
print_r($u_entries);
echo "done";
} else {
die("failed to authenticate user");
}
This line:
$u_result = ldap_search($ldap, $dn, $filter, $u_attr) or exit("Unable to search LDAP server");
seems to work as desired and no error about performing the ldap search.
$u_entries however contains the same information as $entries and this is where I'm having a problem. I'm trying to obtain details about the user and insert them into a local db if they're not already present.
I had the same problem before, check if your LDAP server lets external connections in.
Check your $dn variable if you're using emails only enter the stuff after the # sign
Also be sure that your admin credentials
also this link helped me understand it a bit more:
https://github.com/Adldap2/Adldap2-Laravel/issues/224
Note i worked with Laravel
My attributes array was incorrect and by definition ldap_search will ALWAYS return the DN. Problem resolved.
I searched every days for my problem, I tried many solutions and I didn't find... :(
I want to create an user using ldap_add with PHP. Working fine without enable account and without password. You find the code below.
Can you help me, please?
Config :
PHP 5.6
Windows Server 2012 R2 with AD
I can enable an account when I use $info["useraccountcontrol"]=544; but the account isn't with a password... User must loggon without password and type his new password at the first connection. *
I tried to add a password with $info['userPassword'] and chand useraccountontrol at 512 and I get this error :
ldap_add(): Add: Server is unwilling to perform
Here is my code :
<?php
$name = htmlspecialchars($_POST["name_build"]);
$lastname = htmlspecialchars($_POST["lastname_build"]);
$department = utf8_encode(htmlspecialchars($_POST["department_build"]));
$title = utf8_encode(htmlspecialchars($_POST["title_build"]));
$dn="CN=$name OU=Users, o=Domocom, c=net";
$ds = ldap_connect("192.168.1.1",389);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // IMPORTANT
ldap_bind($ds, "administrateur#domocom.net", "password");
// Prépareles données
$cn = $info["cn"] = "$lastname $name";
$info["sn"]="$name";
$info["givenname"]="$lastname";
$info["displayname"]="$lastname $name";
$info["name"]="$lastname $name";
$info["userprincipalname"]= "$lastname.$name#domocom.net";
$info["samaccountname"]= "$lastname.$name";
$info["title"]="$title";
$info["department"]="$department";
$info["mail"]="$lastname.$name#domocom.fr";
$info["postalcode"]="69009";
$info["objectClass"][0]="user";
//$info['userPassword'] = "password";
//$info["useraccountcontrol"]=544;
$r = ldap_add($ds,"CN=$cn,OU=Users,OU=Direction,OU=Domocom-SP,DC=domocom,DC=net", $info);
ldap_close($ds);
} else {
echo "unable to connect to ldap server";
}
?>
Thanks a lot.
PS : it's fake society for my school. :p
If it's an AD you might need to use a secure LDAP-Connection.
For that you'll need to call ldap_connect('ldaps://192.168.1.1:<port of the AD>');. Calling ldap_connect with two parameters is deprecated and should be avoided. Use it with an LDAP-URI!
You can also omit the if…else around the ldap_connect as it will return true in almost all cases. And a true return-value does not mean that a connection to the server actually as established. A connection is first established on the first ldap_-command that needs a connection which is typically ldap_bind.
And then you might want to have a look at Change AD password using PHP, Issue updating AD password using PHP and Change AD Password using PHP/COM/ADSI/LDAP
My problem is that when i try to retrieve the value of the attribute 'userPassword' it won't work i'm working under PHP , the problem is that the attribute exist when i open Phpldapadmin i can see it , but when i try to retrieve it using this lines of code it won't work
$sr = ldap_search($ds,"ou=people,dc=powerm,dc=com","uid=".$login);
$data = ldap_get_entries($ds,$sr);
$password = $data[0]["userpassword"][0];
$displayName = $data[0]["displayname"][0];
$num_tel =$data[0]["mobile"][0];
$mail =$data[0]["mail"][0]
the others attributes work fine expect the userpassword
can any one help ?
thanks.
Try specifying the attributes you want returned explicitly.
$dn = 'ou=people,dc=powerm,dc=com';
$filter = 'uid=' . $login;
$attrs = ['displayname', 'userpassword', 'mobile', 'mail'];
$sr = ldap_search($ds, $dn, $filter, $attrs);
The directory may be configured not to return this security-sensitive attribute unless you explicitly ask for it.
It may also be that the attribute requires special privileges to access it - are you using the same credentials to connect to the database in your code as you did in phpLDAPAdmin?
The server may also be configured not to return the password unless it's over an encrypted connection - initiated using an ldaps:// URL passed to ldap_connect(), or using ldap_start_tls().