PHP cannot connect to LDAP Oracle Directory Server Enterprise Edition - php

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!

Related

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.

PHP LDAP Connection to Authenticate against Active Directory from External Server

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

can not bind to the LDAP directory with secure connection with php

Installation Information:
I have two Windows servers. One (Windows Server 2008 R2) is a domain controller (DC) with Active Directory (AD).Its name is s1.xyz.com. The second (Windows Server 2003 R2) server is running IIS, PHP.SSL certificate is installed on second server.
I have installed Active Directory Certificate Services on DC server to act as a Certificate Authority (CA) and also enable LDAP over SSL(LDAPS) using below link:
http://www.christowles.com/2010/11/enable-ldap-over-ssl-ldaps-on-windows.html
What is the problem:
Actually, I want to set password for AD users so my requirement is secure connection(LDAPS) to do so.
I can successfully connect to the DC on unsecured port (389) and access AD data but
I can not bind user on secure connection (on port 636) using PHP ldap_bind() function.
When i run the script it gives "ldap_bind() [function.ldap-bind]: Unable to bind to server: Can't contact LDAP server" error.
Code:
$ip="xxx.xxx.xxx.xx";
$ldaps_url="ldaps://s1.xyz.com:636/";
$ldap_url="s1.xyz.com";
$ldapUsername ="Administrator#xyz.com";
$ldapPassword="x1y1z1";
$ds=ldap_connect($ldaps_url);
//$ds=ldap_connect($ip,636);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($ds, LDAP_OPT_REFERRALS,0);
$bth=ldap_bind($ds, $ldapUsername, $ldapPassword);
ldap_unbind($ds);
$ds="";
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. For example:
<?
ldap_connect('ldaps://ldap01');
// 'ldap01' should match the CN in your LDAP server's SSL cert, otherwise the subsequent ldap_bind() will throw a bind error
?>
You can have a look to your certificate using Microsoft MMC.
Maybe s1.xyz.com cannot be resolved. Try it with the ip instead. Like ldaps://ip.goes.here:636.

PHP LDAP not working securely

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.

Categories