I am tried to implement a LDAP authentication in my web application developed in ZF2. LDAP authentication is working fine in Windows 7.
But, after moving the application to LINUX machine, LDAP authentication is not working. I am always getting the error as : Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server in LdapConnect.php on line 20
I have used the scripts as:
$ldaphost = "ldap://xxxx.net";
$ldapport = 389;
$ds = ldap_connect($ldaphost, $ldapport) or die("Could not connect to $ldaphost");
if ($ds)
{
$username = "username#xxxx.net";
$upasswd = "password";
$ldapbind = ldap_bind($ds, $username, $upasswd);
if ($ldapbind)
{
print "Congratulations! you are authenticated successfully.";
}else{
print "Better luck next time!";
}
}
Should I install any software package or should I do any config settings?
Note: If I give the IP adress then it is working fine, but if I give the domain name, then it is not working.
The library may be different between the 2, or a different version. You'd be amazed how many variations of the ldap client there are. In your position I would (if available) use ldap client to make the same kind of connection a few different ways.
e.g. the "-x" on the standard ldapsearch:
-x Use simple authentication instead of SASL.
So you could express the connection like this:
ldapsearch -h xxxx.net -p 389 (etc)
ldapsearch -x -h ldap://xxxx.net:389 (this should actually be -H..)
and so on.
It is also possible for things outside of your code to be an issue. Prod servers often have firewalls and proxies (e.g. F5) that are transparent to the server/client.
Make sure your final code has exception handling for binding and searching. I'm not too familiar with the php implementation, and the doco is a tad thin. Normally you'd use a synchronous bind.
Can you verify that the code above is exactly as you had it on Windows? The reason I ask is that looking here: http://php.net/manual/en/function.ldap-connect.php it seems that you may be mixing 2 types of bind. I definitely wouldn't have done it like that in standard python.
So if using a URI normally you'd do it like this:
ldap_connect("ldap://blah:389")
and if you're connecting via host/port combo:
ldap_connect("blah","389")
With minimal exception info my best guess is that its actually trying to bind to a hostname "ldap://xxxx.net" on port "389".
Related
I've got here an Windows Server 2008r2 set up with Active Directory, DNS, DHCP and DC for testing purposes and i am quite new to LDAP.
I want to change the password for myself, even though if i am no
admin.
So, here is my script i am working on right now:
// LDAP Variables
$serverip = "192.168.2.1";
$serverport = 636;
$username = "user";
$userpassword = "password1";
$newpass = "password2";
$userDn = "CN=$username,CN=Users,DC=dc-name";
$ldapconn = ldap_connect($serverip, $serverport) or die("LDAP Connection Failed!\n");
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($ldapconn) {
echo "Connection succeded\n";
// LDAP Bind
$bindresult = ldap_bind($ldapconn, $username, $userpassword);
if ($bindresult) {
echo "Bind: Succeded\n";
$userData['unicodePwd'] = toPwEntry($newpass);
$modresult = ldap_mod_replace($ldapconn, $userDn , $userData);
if (!$modresult) echo "PW Change Failed - Error No. ". ldap_errno($ldapconn).": " .ldap_error($ldapconn) . "\n";
}
else echo "Bind Failed - Error No. ". ldap_errno($ldapconn).": " .ldap_error($ldapconn) . "\n";
}
else echo "Connection failed - Error No. ". ldap_errno($ldapconn).": " .ldap_error($ldapconn) . "\n";
function toPwEntry($pw) {
return("\"". iconv('UTF-8','UTF-16LE',$pw) ."\"");
}
ldap_close($ldapconn);
when i start the script i get this error:
soenke#work:~/Desktop/$ php ldap.php
Connection succeded
Bind Failed - Error No. -1: Can't contact LDAP server
i also tried connections by using "ldaps://" in front of the ip but it doesn't work.
i would appreciate any help!
A couple of suggestions:
ldap_bind() wants $userDN rather than $username. That would cause a different error message though.
There's no actual network traffic between your web server and the ldap server until you call ldap_bind(), so make sure there aren't any firewall/network issues, etc. The error message says "Can't contact the server"; that might be exactly what's happening. (The ldap_connect() function just initializes a local struct in later versions of ldap libraries. You could think of it more like "ldap_init()" -- the "Connection succeeded" message doesn't imply a successful network connection here.)
You can setup an LDAP server to handle both secure and insecure connections on 389 instead of 636. Make sure you're connecting where the server expects you to.
These symptoms might also show up if your end of the TLS connection fails to verify the server certificate. You either have to provide root certificates to trust, or configure your client to not verify the cert (if the server has a self-signed certificate, for example). Either of those can be accomplished by setting variables in an ldap.conf file. Where to put ldap.conf depends on your web server setup.
This: http://www.novell.com/coolsolutions/tip/5838.html and this: http://www.whatsnoodle.com/php-ldap_bind-gives-the-error-cant-contact-ldap-server/ might have more details for you.
Active Directory will only let you change passwords via LDAPS and I'm pretty sure you have to use port 636.
When you specify LDAPS:// try it in upper case. At least one of the MS provider monikers is case-sensitive. I'm not completely sure it's the LDAP one; I've used caps for all monikers for years.
Your password, I think, has to be an octet string (byte array). I can't read PHP so I can't tell if that's what you're doing but I'm guessing so.
Your domain controller will need a certificate to do LDAPS. I'm no certificate expert but I think the name you use for the server has to match the one on the certificate and it's not normally the IP address (though I think you can put them in alternate names on the cert) so I think you should be using the server name.
It is the first time I am working with PHP 5 LDAP library and I am a bit confused. I would be very happy if anyone could give me some clarifications on the following:
First of all let me give my configurations:
LDAP server: Windows Server 2013 Active Directory
Hostname: winad
Domain: domain.local
IP: 1.1.1.1 (for the sake of explaining)
Windows Account used for binding: Administrator
Ping hostname from dev machine works
Ping ip from dev machine works
Ping winad.domain.local from dev machine fails
Development Environment: Windows 8 Professional with WAMP
PHP: 5.3.13
PHP LDAP Module loaded and working
Apache LDAP module not loaded
Scenario:
I am trying to authenticate a user against the Windows AD with the administrator account for a start. Here is a sample of my code:
I will be using these variables in the various scenarios below:
$hostname = "winad";
$dnex= "uid=Administrator, ou=Users, dc=domain, dc=local";
Code that works:
$conn = ldap_connect($hostname);
$bind = ldap_bind($conn, "DOMAIN\Administrator", "password");
Code that fails:
$conn = ldap_connect($hostname);
$bind = ldap_bind($conn, $dnex, "password");
Error: Invalid credentials
Now my question is why does it fails when I specify a dn?
Let say I have location1.domain.local and location2.domain.local and I want to bind only with location2, it does not seem possible without specifying the dn.
Can somebody show the right way to proceed?
After some more search I found the following post:
PHP LDAP Connection
The response from AlexC answered my question correctly.
Hope this is helpful.
I have an Active Directory server and a Windows WAMP server hosting PHP web applications that need to be able to authenticate to Active Directory using Kerberos.
I was able to easily connect and bind to the Active Directory host using some sample PHP code, but I'm not sure how to do so with Kerberos. I have see many forums and blogs detailing how to do this on *NIX machines, but that doesn't help me with my situation.
I did use Wireshark and Fiddler to confirm that there is no Kerberos or NTLM negotiating happening.
Sample code I used to connect and bind to LDAP:
<?php
$ldaphost = "example.domain.com";
$ldapport = 389;
$ldapuser = "user";
$ldappass = "password";
$ldapconn = ldap_connect( $ldaphost, $ldapport )
or die( "Unable to connect to the LDAP server {$ldaphost}" );
if ($ldapconn)
{
$ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass);
if ($ldapbind)
{
echo "LDAP connection successful";
}
else
{
echo "LDAP connction failed";
}
}
?>
Any help will be greatly appreciated, thanks!
Update: I've been wrestling with this all day and I think I need to use ldap_sasl_bind(), possibly using GSSAPI as the mechanism... No matter what parameters I put in to ldap_sasl_bind(), I get the following error: 'Unable to bind to server: Unknown authentication method'
I'm not sure how to implement GSSAPI, but some examples I've seen show using ldap_start_tls(), but I keep getting a 'Unable to start TLS: Server is unavailable' error.
I don't know if anyone knows anything about ldap_sasl_bind() (which is undocumented by PHP) or ldap_start_tls, but if this is the way I should be going, please point me in the right direction.
I cannot help with the Kerberos issue yet, as I am still struggling with it myself. However, I can point you in the right direction for TLS. TLS will at least prevent your credentials from being transmitted over the network in clear text. TLS requires proper configuration of OpenLDAP. At the very least, you can configure your client to not request or check any server certificates. You do this by adding the following line to the top of your ldap.conf configuration file.
TLS_REQCERT never
Your ldap.conf file should be located in C:\ or C:\openldap\sysconf, depending on your version of PHP and OpenLDAP. The file most likely does not yet exist in your setup. You may also be able to set the configuration via an environment variable as well putenv(TLS_REQCERT=never);, but I have not tried that myself, and there appear to be mixed results reported by others.
What you need to do: Make sure that the LDAP interface in PHP is compiled against SASL, supports GSS-API mech and either uses keytabs or the Windows-own SSPI interface. Good luck.
I solved this problem on windows by creating executable based on c++ ldap_bind_s. I use this executable as a command line with the parameters: host, username,password. This is the only way I got it work for GSSAPI.
WINLDAPAPI ULONG LDAPAPI ldap_bind_s(
LDAP *ld,
const PSTR dn,
const PCHAR cred,
ULONG method
);
I used LDAP_AUTH_NEGOTIATE.
I have an external web server trying to authenticate against Active Directory on an internal server via LDAP. I am able to connect and authenticate locally, though using the same code (switching out host and port) am not able to authenticate externally. We have other services that are able to connect and authenticate such as Attask (http://www.attask.com/).
The external server is currently a Linux (gs) on Media Temple running PHP 5.3.15 with LDAP support enabled.
The internal server is currently a Windows Server 2008 box with LDAP and Active Directory.
The code below is the current PHP I am using that was able to connect locally, but having problems on the external server. It basically uses the PHP LDAP connection string and tries to bind. If it fails, it tries to bind anonymously. Both of which aren't working externally and returns the error: Can't contact LDAP server.
<?php
$username = 'username';
$password = 'password';
$ldapconfig['host'] = '00.000.000.000';
$ldapconfig['port'] = '636';
$ldapconfig['basedn'] = 'dc=client,dc=eqc,dc=local';
$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ds, LDAP_OPT_NETWORK_TIMEOUT, 10);
$dn="".$username."";
if ($bind=ldap_bind($ds, $dn, $password)) {
echo("Login correct");
} else {
echo("Unable to bind to server.</br>");
echo("msg:'".ldap_error($ds)."'</br>".ldap_errno($ds)."");
if ($bind=ldap_bind($ds)) {
$filter = "(cn=*)";
if (!($search=#ldap_search($ds, $ldapconfig['basedn'], $filter))) {
echo("Unable to search ldap server<br>");
echo("msg:'".ldap_error($ds)."'</br>");
} 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]);
}
}
} else {
echo("Unable to bind anonymously<br>");
echo("msg:".ldap_error($ds)."<br>");
}
}
?>
A few notes:
The external LDAP server is using LDAPS so the suggested host is ldaps://00.000.000.000 on port 636
I've tried binding with 'username' as well as 'username#00.000.000.000' already
There is a firewall, however, the external server can successfully ping the internal LDAP server so there is connection taking place on that level.
Any help would be greatly appreciated. If there are server settings or things of that nature, would love to know. Also, I've checked out ADFS though could not find a simple script to setup to test without spending a lot time to no end if it didn't work.
When connecting to AD using LDAPS from a Linux box, I've always had to add the line
TLS_REQCERT never
in /etc/ldap.conf or equivalent (might require an apache restart - not sure). You can also try the format "ldaps://server.domain.tld:636" for the host, though I don't think that's the issue.
I found some decent documentation at http://en.gentoo-wiki.com/wiki/Active_Directory_Authentication_using_LDAP, though it appears to be down at the moment. Google's cached version: http://webcache.googleusercontent.com/search?q=cache:http://en.gentoo-wiki.com/wiki/Active_Directory_Authentication_using_LDAP
Have you checked if it is an SSL certificate error? Are you using a self signed cert or an official one?
"If you're using SSL (e.g. ldaps) and ldap_bind is throwing 'Unable to bind to server:' errors, check that the hostname used in the ldap_connect matches the 'CN' in the SSL certificate on the LDAP server" Source
I am trying to get a LDAPs client in PHP working. My code is in place, and it works using the standard LDAP protocol.
However, when I change ldap://server to ldaps://server, it doesn't work. Setting the debug mode to 7 yields this error. I should add that this a linux server using openSSL.
TLS: can't connect: The Diffie Hellman prime sent by the server is not acceptable (not long enough)..
Is there any way to get past this? Changing anything on the LDAP server is not an option as I only have client privileges on it.
EDIT: Only setting in my LDAP.conf is
TLS_REQCERT never
EDIT2: Here is my code
if(isset($_POST['pass'])){
$username = $_POST['user'];
$password = $_POST['pass'];
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$ds=ldap_connect("ldaps://server.com");
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3) ;
//Check LDAP server for user
if(!#ldap_bind($ds, "uid={$username},ou=people,o=site.ca,o=site", "{$password}") || strlen($password)==0){
// LDAP login was not successful
printf("Sorry, wrong username/password\n\n\n");
return;
}
$ldapSearch=#ldap_search($ds, "ou=people,o=site.ca,o=site", "uid={$_POST['user']}");
$result = #ldap_get_entries($ds, $ldapSearch);
}
This could be due to a bug in your version of libgnutls
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=440344
First of all, this is for Ryerson? Come on! (I used to work at York U! Gotta tease the guys downtown a little. Could be worse, you could be at U of T!). But seriously, depending on your LDAP server at the backend, there are two usual approaches.
ldaps://ldap.ryerson.ca:636 might work better, in that it will try and do an SSL bind, expecting you have trusted the public key of the CA that signed the certificate in use for SSL.
TLS is really SSL V3.1 and one of the very nice features it adds is that it works fine on port 389 as well, but can issue a StartTLS command which takes a clear text connection you started on 389 and enables encryption.
My suspicion is that from the error code it is trying to make an LDAP over SSL on the clear text port which will fail.