Php ldap bind - Unable to bind to server: Invalid credentials - php

I have checked tons of solutions for this problem and yet none of them solved my problem, I am building a laravel app and need to authenticate users against AD for that purpose I found that I can accomplish this with the following script
$ldap_dn = "uid=user,dc=example,dc=local";
$ldap_password = "somePassword";
$ldap_con = ldap_connect("ldap://domain") or die("Could not connect to LDAP server.");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap_con, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($ldap_con, $ldap_dn, $ldap_password);
if($bind)
{
return "Authenticated";
}
However, I keep getting the same error, no matter how I change my parameters. Here's a list of things I've tried:
modifying this line $ldap_dn = "uid=user,dc=example,dc=local"; to:
$ldap_dn = "cn=user,dc=example,dc=local";
$ldap_dn = "uid=domain\user,dc=example,dc=local";
$ldap_dn = "sAMAccountName=user,dc=example,dc=local";
I am sure my credentials are correct, I have tested this in C# and it works perfectly with the following script:
public static bool IsAuthenticated(string ldap, string usr, string pwd)
{
bool authenticated = false;
try
{
DirectoryEntry entry = new DirectoryEntry(ldap, usr, pwd);
object nativeObject = entry.NativeObject;
authenticated = true;
}
catch (DirectoryServicesCOMException cex)
{
}
catch (Exception ex)
{
}
return authenticated;
}
I even tried compiling a c# dll to bypass ldap binding in php but got to a dead-end with that solution too...

Related

LDAP insert new user

I have windows server 2012 and i want to insert new user using ldap and php
the connection to ldap server is ok but I can not insert new user
and I have more than one error every time I change the dn code
the last error I have is
Warning: ldap_add(): Add: Naming violation in C:\AppServ\www\auth\insert.php on line 36
the code of my php file is
<?php
$ip = "10.10.10.35:389";
$ldap_url = "ldap://$ip";
$ldaps_url = "ldaps://$ip";
$ldap_domain = 'peace.world';
$ldap_dn = "dc=peace,dc=world";
$ldap_conn = ldap_connect($ldap_url)
or die("Could not connect to LDAP server ($ldap_url)");
echo $ldap_con;
if ($ldap_conn)
echo " connected";
$username = "captiveportal";
$password = "123";
$result = ldap_bind($ldap_conn, "$username#$ldap_domain", $password)
or die("<br>Error: Couldn't bind to server using supplied credentials!");
if ($result) {
ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
$dn = "cn=Users,DC=peace,DC=world";
echo $dn;
$info["cn"] = "muh Jones";
$info["sn"] = "muh";
$info["objectclass"] = "person";
try {
## Heading ##
$r = ldap_add($ldap_conn, $dn, $info);//36 line the error is here
--------------------------------------
}
catch (Exception $e) {
echo $e;
}
} else
echo "cannot connect to ldap";
the image of my active directorty users and computers is enter image description here
You do indeed have a naming violation. You are trying to add a new entry with DN "cn=Users,dc=Peace,=dc=world" but that DN is already taken as it's the DN of the entry that holds all users. You most likely want to add a DN "cn=muh Jones,cn=Users,dc=Peace,dc=world"
Besides that there are probably some attributes missing like f.e. samaccountname but thats most likely not what causes your error.
Additionally I'd recommend to set the Protocol version right after the ldap_connect!

Getting user readable name via LDAP with PHP by having only the login credentials

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;
}

ldap auth with php fails intermittently

I have put together a basic web-app, the actual web-app itself works fine. However I wanted to add user authentication using our existing ldap server. The ldap script seems to work intermittently though, when logging in the first few attempts will fail with the 'access denied' message then it will authenticate. I ran the script stand alone without the app and the same behavior applies.
I cant seem to tie the problem down anywhere, I can only assume it is occuring on the ldap side and not the php side. I have included the script below, any help would be great.
While writing this, it failed to auth 3 times and passed twice...
<?php
$user = $_POST['login-name'];
$password = $_POST['login-pass'];
$ldap_user = 'uid='.$user.',ou=people,dc=ourdomain,dc=com,dc=au';
$ldap_pwd = $password;
$ldaphost = 'ldap://ldapserver.domain.com';
$ldapport = 389;
$ds = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to $ldaphost");
if ($ds)
{
$username = $ldap_user;
$upasswd = $password;
$ldapbind = ldap_bind($ds, $username, $upasswd);
if ($ldapbind)
{
//print "Congratulations! $username is authenticated.";
header('Location: message.html');
}
else
{print "Access Denied!";}
}
?>
You probably should set the LDAP-protocol version to 3 using
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
before calling ldap_bind().
I've found this at http://php.net/manual/de/function.ldap-bind.php#72795

ldap_bind(...) php gives invalid credentials while ldp.exe works

I have serious trouble figuring out which credentials to use to connect to the ad in php.
I can connect successfully using ldp.exe with generic function type and the right domain, user, and password. With any other option set in ldp.exe I can only connect anonymous.
In php I have no chance. I'm not very familiar with ldap, so I am kinda lost here.
Here some php code:
$ldap_host = "ldap://<dc>:389";
$ldap_user = "<username>";
$ldap_pw = "<pw>";
$ldap_domain = "<full domain>";
$connection = ldap_connect($ldap_host) or die("Could not connect to LDAP server.");
//$user = $ldap_user;
$user = $ldap_user."#".$ldap_domain;
//$user = $ldap_user;
//$user = "uid=".$ldap_user;
//$user = $ldap_domain."\\".$ldap_user;
//$user = "User=$ldap_user";
//$user = "cn=".$ldap_user;
//$user = "CN=".$ldap_user.",OU=<someOU>,OU=<someOU>,DC=<DC1>,DC=<DC2>";
ldap_bind($connection, $user, $ldap_pw);
You can see there some combinations I tried. In ldp.exe it is just the $ldap_user in the username field and $ldap_domain in the domain field. Imho atleast the user#domain and domain\user version should work. It is a kerberos domain, if thats important.
Well I don't think there are code errors. But how do I translate the generic function type of ldp.exe into php?
Here the error message to make it easier to find:
Warning: ldap_bind(): Unable to bind to server: Invalid credentials in ...
I would really appreciate some help.
EDIT: In ldp.exe I seem to use the SSPI method. I thought generic picks the method it self so far. Does it have something to do with ldap_sasl_bind() ? The server specifies on connection he is capable of the following:
supportedSASLMechanisms: GSSAPI; GSS-SPNEGO; EXTERNAL; DIGEST-MD5;
While only GSSAPI (SSPI ????) seems to work.
EDIT2: Here some other output of ldp.exe after an successful authentication:
res = ldap_bind_s(ld, NULL, &NtAuthIdentity, 1158); // v.3
{NtAuthIdentity: User='<username>'; Pwd= <unavailable>; domain = '<full domain'.}
Authenticated as dn:'<username>'.
Try specifying the port as well into a variable
$ldapPort = 389;
I would ignore the host part and just try connecting to your server (you have it as domain) Check to see if your ldap bind is working
// Handle login requests
$ds = ldap_connect($ldapServer, $ldapPort);
if (ldap_bind($ds, $user, $password)) {
// Successful auth
$_SESSION['lastactivity'] = time();
$_SESSION['username'] = $user;
$_SESSION['password'] = $password;
return $ds;
} else {
// Auth failed
header("Location: failpage.php?fail=1"); //bad credentials
exit;
}
Also for calling all the attributes, try http://blog.uta.edu/jthardy/2007/08/08/obtaining-user-information-from-ldap-using-php/

PHP LDAP binding AD with the server's user account

I have some code that uses PHP and LDAP to connect to AD:
$host = 'ldap://stack.overflow.com';
$port = 389;
$username = 'stackOverflow';
$password = 'IaMP4ssWord';
$dn = 'CN=Users, DC=STACK, DC=OVERFLOW, DC=COM';
$cond = '(&(objectcategory=user)(displayname=*))';//All users that have a displayname
if($ldap = ldap_connect($host, $port))
{
if(ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3))
{
if(ldap_bind($ldap, $username, $password))
{
$attrs = array('displayname', 'mail');
if($rs = ldap_search($ldap, $dn, $cond, $attrs))
{
$results = ldap_get_entries($ldap, $rs);
echo "<pre>";print_r($result);echo "</pre>";//Print the results
}
}
else
{ echo 'Binding failed';}
}
else
{ echo 'Setting options failed';}
}
else
{ echo 'Connection failed'; }
Now this code works just fine. It print out every user that has a displayname in AD.
Problem is for the username/password binding i am using my own user credential to bind to the server.
I would like to know if there is a way to bind using the servers credentials.
I am setup using PHP 5.3 + IIS on windows server 2008 R2 for both the server with IIS and the one that has AD.(two different VM).
I also know that IIS has a AD account named IISStackOverflow but I don't know the password or even if it has a password...
Thanks!
Oh! I tried changing $username to IISStackOverflow and $password to ''
But it gave invalid credential error.
--EDIT--
Do I have to do the binding part at all? (If I am only reading data)
As you run it from server itself, and you just want to read I would try to use :
...
if(ldap_bind($ldap))
...
According to PHP documentation if bind_rdn and bind_password are not specified, an anonymous bind is attempted.
Then if your anonymous logon is refused (this should not be, because running under IIS on the server your code is at least executed as a domain user) you will find there how to enable anonymous LDAP binds to Windows Server. This used to work forme on W2K8, Inever test it on W2K12.

Categories