PHP LDAP Connection to Authenticate against Active Directory from External Server - php

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

Related

PHP on IIS - unable to bind to Active Directory over LDAPS

I'm working on a small password reset script for our users, using PHP5 on an IIS7.5 server. I have LDAP over SSL enabled on our Active Directory controllers, and tested that it is working properly using ldp.exe
Here's the code to connect to the server:
$ldap_server = "ldaps://AD02.district.local";
$ldap_port = "636";
$ldap_user = "service_lookup#district.local";
$ldap_pass = "(goes here)";
$ds = ldap_connect($ldap_server,$ldap_port);
ldap_bind($ds,$ldap_user,$ldap_pass);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
However, when I execute the script, I get the following error:
Warning: ldap_bind() [function.ldap-bind]: Unable to bind to server:
Can't contact LDAP server in D:\Sites\Lookup\search.php on line 11
If I set $ldap_server to use ldap:// instead of ldaps://, it'll connect (even with the port set to 636), but the actual reset function does not work ("server is unwilling to perform").
Is there a way to troubleshoot this further? Or does anyone know what may be wrong?dd
I know this is an old question. But today I encountered the same problem.
I had to apply the following solution to make it work:
Create a folder: C:\OpenLDAP\sysconf
Create a file 'ldap.conf' in C:\OpenLDAP\sysconf.
Make the content of the file: 'TLS_REQCERT never' (no quotes).
Save.
It should work now. According to the manual, “TLS_REQCERT never” prevents the server from requesting and/or checking any server certificate.

PHP LDAP Windows 2008r2 Change users password

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.

How to perform a LDAP SASL bind to Active Directory using GSS-API mech in PHP from Windows?

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.

Connecting to a non-secure LDAP server via PHP on a Secure Domain

I am trying to connect to an ldap server that the client's IT guy says does not have an SSL certificate. This is on a test file on their domain, which has an SSL installed. Let's say the file is at https://client.org/test_LDAP.php
So I use very simple code to connect, which has worked fine with another client just in the past month:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
define("LDAP_SERVER","ldap://name.their.junk");
define("LDAP_BASE","CN=Users,DC=their,DC=junk");
$username = 'CN=Username,'.LDAP_BASE;
$password = "Password";
$ldap = ldap_connect(LDAP_SERVER, 389) or die("Can't connect to LDAP server");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3) ;
if (ldap_bind($ldap, $username, $password)) {
ldap_unbind($ldap);
echo 'OK - Login valid';
} else {
die(ldap_error($ldap) . ' (' . ldap_errno($ldap) . ')');
}
If I am running code from a domain with an SSL installed, does that mean I HAVE to use ldaps and port 636, even if the client's AD server doesn't have a Certificate? I've tried the code with both ports and both ldaps: and ldap: on an unsecured launch domain and also his secured live domain. Nothing seems to work. But he swears the username and password and all of the variables are correct, and told me to use their IP instaed of the hostname (ldap:000.000.000.00 for example).
Am I doing something wrong here?
And yes, I DO have LDAP configured correctly on my server end, because we just were able to do this exact same thing with another client recently.
Any insight would be much appreciated.
If you try to perform the searches on Windows 2003 Server Active Directory or above, it seems that you have to set the LDAP_OPT_REFERRALS option to 0:
ldap_connect(..)
ldap_set_option ($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind(..)

PHP cannot connect to LDAP Oracle Directory Server Enterprise Edition

Been playing with this for days and can not get php to bind to ldap on Oracle's DSEE.
function test(){
// LDAP variables
$ldaphost = "xxx.xxxxx.com";
$ldapport = 636;
$ldaprdn = 'cn=xyxyxyxy,ou=Accounts,dc=xxx,dc=xxxxx,dc=com';
$ldappass = 'vcvcvcvcvc';
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7); // isn't helping
// Connecting to LDAP
$ldapconn = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to $ldaphost");
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...";
}
}
}
I get the error:
Message: ldap_bind() [function.ldap-bind]: Unable to bind to server: Can't contact LDAP server
Tearing my hair out on this one. I just can't get the thing to bind.
Have tried a straight telnet to the host on port 636 and am not being blocked by any firewall. Peculiarly I am not getting any extra debug info from the 'LDAP_OPT_DEBUG_LEVEL' on screen or in my logs.
start_tls() and ldaps is mutually exclusive, meaning you cannot issue start_tls() on the ssl port (standard 636), or initiate ldaps on an unecrypted port (standard 389). The start_tls() command initiate a secure connection on the unencrypted port after connection is initiated, so you would then issue this before the bind takes place to make it encrypted. Another set of common ports is 3268 (unecrypted) and 3269 (ssl) which might be enabled in your server.
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
is logging to your web servers error log, depending on your log level, or to stout (from PHP CLI). To gain more information here, check your web server log level setting, or simply run your php script from command line.
To successfully use the ssl port, you need to specify the ldaps:// prefix, while on the unencrypted port this is not necessary (with a ldap:// prefix).
Looking at your code, this could be a protocol version issue as PHP by default use version 2. To solve this, you can issue:
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($conn, LDAP_OPT_REFERRALS,0);
before you attempt to bind.
You can also have a look at the code in Problems with secure bind to Active Directory using PHP which I successfully use in CentOS 5, but is having problems in Ubuntu. If your server has an open unencrypted port, it's a good idea to do an unencrypted test bind against it to rule out any connectivity issues.
To check if the port is open, you can check if telnet connects to it, E.G:
telnet my.server.com 3268
If the port is open, then you should be able to bind using it.
*Edit: If the ssl certificate is deemed invalid, the connection will fail, if this is the case, setting the debug level to 7 would announce this. To get around this specific problem you need to ignore the validity:
You can ignore the validity in windows by issuing
putenv('LDAPTLS_REQCERT=never');
in your php code. In *nix you need to edit your /etc/ldap.conf to contain
TLS_REQCERT never
The port 636 is the SSL enabled port and requires an SSL enabled connection.
You should try to connect on port 389, or change your code to include the secure layer (much more complex).
Kind regards,
Ludovic
To connect using SSL you should try
$ldapconn = ldap_connect('ldaps://'.$ldaphost);
This will automatically connect on port 636 which is the default ldaps-port. Depending on your server installation and configuration it may be possible that connections are only allowed on port 389 (using no encryption or using TLS) or only on port 636 using SSL-encryption. Although it might be possible that your server exposes other ports. So in general you need to know which port you're gonna connect to and which encryption method the server requires (no encryption, SSL or TLS).
Is the certificate of the LDAP server signed by a valid CA? Maybe your client just rejects the certificate!

Categories