I'm trying to understand PHP's ldap function in order to debug an app.
The authentication flow is like following:
ldap_connect($host, $port);
ldap_set_option($ds, $option);
ldap_bind($ds, $rdn, $pwd);
ldap_search($smth);
ldap_get_entries($smtgelse);
ldap_close($ds);
The error I get is:
The gateway did not receive a timely response from the upstream server or application.
I suspect a firewall to block the response, but I put a logger to see which statment is blocking, it's the ldap_bind one's.
If it's a network issue it should block on the ldap_connect statment shouldn't it?
From the PHP documentation - http://php.net/ldap_connect:
When OpenLDAP 2.x.x is used, ldap_connect() will always return a resource as
it does not actually connect but just initializes the connecting parameters.
The actual connect happens with the next calls to ldap_* funcs, usually with
ldap_bind().
Related
I need to create a SpringBoot service and provide an authentication service using LDAP.
I followed this example and it works fine for me using an embedded local ldap server (as suggested into the tutorial)
Now I tried to use the official company LDAP server but I got this error:
Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4563];
This error seems related to a LDAP bind request that it's necessary. But how can I add this into the Spring Security LDAP?
This is the code where I tried to integrate the company LDAP connection:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("userPrincipalName={0},ou=users")
.groupSearchBase("ou=users")
.contextSource()
.url("ldap://companyhost:389/dc=aa,dc=company,dc=com")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
}
I tried also with my PHP example (using the official company active directory and this works fine)
// connect to ldap server
$ad = ldap_connect("ldap://".LDAP_HOST, LDAP_PORT)
or die("Could not connect to LDAP server.");
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);
$user = $_POST['username'];
$password = $_POST['password'];
if (ldap_bind($ad, "$user"."#".LDAP_HOST, $password)) {
// User authenticated
}
The Directory Server you are connecting to does not allow 'anonymous' access, i.e. your application first has to authenticate beforehand (via and LDAP BIND operation) before performing queries. LdapContextSource
Furthermore Using password comparision ('passwordCompare()') is not LDAP best practice (I don't know why this is still in the Spring docs), itstead an LDAP BIND operation should be used to authenticate users. This lets the server compare the password as only the server knows which password storage scheme was used on the server side when the password was saved.
Using 'userDnPattern' is also not LDAP best practices as this means you have to know the Directory Information Tree (DIT) of the LDAP Directory Server. Instead let the Directory Server determine the Distinguished Name (DN) by performa search leveraging 'userSearchBase', 'userSearchFilter' LdapAuthenticationProviderConfigurer
I'm currently implementing LDAP Authentication. I cache the credentials as a fallback in case the LDAP server is offline. As part of this caching I need to check if my LDAP server is online. Rather than using PHP's Ldap methods it would be better to use something simple like a ping.
Please note that it should be able to handle any protocols. E.g., I can't use fsockopen because it does not support ldaps://. [I know that I could register my own protocol wrappers].
I want this check to be generic and simple.
I'm using fsockopen for exactly that purpose. It doesn't matter whether it supports ldaps or not I figured out, because there are two possibilities in the end:
The appropriate port is open, so I can assume that the LDAP-Server is up and running or
The appropriate port is not open, so I can assume that the LDAP-Server is not running.
You can check that like this:
$fp = #fsockopen($host, $port, $errno, $errstr, 30);
if (! $fp) {
// Port is unavailable
}
fclose($fp);
Now you know, the port to connect to is open and I can fire up LDAP.
I've found two edge-cases that you won't be able to check for using this method though
The LDAP-Server is in an undefined state and has the port still open but is not responding or
Some other application has opened the port.
You can check that though by using
$con = ldap_connect($ldapURI);
if (! ldap_bind($con, $user, $password)) {
// Something is fishy
}
Fishy might be invalid credentials (which should not happen at this first bind, right?) or the server listening on that port is not responding in a manner that we expect. So it's either not an LDAP-Server or the server is in an undefined state.
To fail fast, you should adapt the timeouts appropriately so you're not waiting half a minute just to know that something went wrong.
YOu can set the timeout for fsockopen using the fifth parameter and you can set the timeouts for LDAP using
ldap_set_option($con, LDAP_OPT_NETWORK_TIMEOUT, [whatever is appropriate]);
ldap_set_option($con, LDAP_OPT_TIMEOUT, [whatever is appropriate]);
ldap_set_option($con, LDAP_OPT_TIMELIMIT, [whatever is appropriate]);
// Only available when your LDAP-extension is compiled against the Netscape LDAP C-SDK
ldap_set_option($con, LDAP_X_OPT_CONNECT_TIMEOUT, [whatever is appropriate]);
You'll need to set them after ldap_connect but before ldap_bind.
LDAP_OPT_TIMEOUT and LDAP_X_OPT_CONNECT_TIMEOUT are not (yet) documented on php.net though!
For more infos on these constants have a look at https://linux.die.net/man/3/ldap_set_option but beware that not all the constants mentioned there are implemented in the PHP-LDAP-Extension.
I am new in LDAP and I have issue with binding.
Here is my code:
$con = ldap_connect(11.11.11.11); // LDAP server is placed at another machine
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($con, "cn=Michael,cn=Users,DC=example,DC=com", "password");
Looks like everything is fine with connection. The error appears on ldap_bind:
ldap_bind(): Unable to bind to server: Internal (implementation
specific) error
I have tried to google this error but found nothing. When I change DN to incorrect on purpose another error apears that says "bad credentials". It means everything is fine with DN and password. Please, help.
The cn of "Users" (cn=Users) is likely to be your organizational unit (ou).
Have you tried the DN: "cn=Michael,ou=Users,DC=example,DC=com" ?
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".
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.