Reputation: 2200
Because of various customers environments running the same code, I'm trying to build an LDAP authentification system with PHP that may work in 3 modes :
Here is a simplified version of the code :
// ldap_connect is successful and returns $ldap
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER); // I tried ALLOW and TRY as well and got the same results
// $configStartTls contains 1, 2 or 3 (see options above)
if ($configStartTls > 1) {
$tlsOk = ldap_start_tls($ldap) || ($configStartTls === 2);
} else {
$tlsOk = true;
}
if ($tlsOk) {
// ldap_bind here
}
Here are the results with a LDAP server that does not support TLS (ldap_start_tls
always returns false), for each value of $configStartTls
ldap_bind
is successful - OKldap_bind
fails - KOldap_bind
is not attempted - OKIn case 2 :
ldap_start_tls
logs "Connect error" with error code 11ldap_bind
logs "Can't contact LDAP server" with error -1I don't understand why ldap_bind
fails in case 2. It's as if using ldap_start_tls
made the use of TLS mandatory. I expected it would be possible to keep communicating with the LDAP server after a failure, in a non-secured way.
Do I have to cancel the use of StartTLS, after a failure, to implement option 2 ? How would I do this ?
Upvotes: 0
Views: 492
Reputation: 2200
I simply needed to do ldap_connect
again to start over without using StartTLS. I had tried that and failed, but only because I forgot to re-apply the LDAP options between ldap_connect
and ldap_bind
, which means I was probably using LDAP v2 on the second attempt, and that's why the server refused it.
Here is full working code. It includes URI, BindDN and password of a free public LDAP server with no TLS support, so anyone who would face the same problem can try the code themselves and tinker with it. Just change the value of $startTlsMode
to any of the constants to try other modes.
const TLS_NO = 1;
const TLS_OPTIONAL = 2;
const TLS_MANDATORY = 3;
$startTlsMode = TLS_OPTIONAL;
$ldap = connectAndSetOptions();
if ($startTlsMode === TLS_OPTIONAL || $startTlsMode === TLS_MANDATORY) {
$tlsOk = ldap_start_tls($ldap);
} else {
$tlsOk = true;
}
// TLS optional and StartTLS failed, start over without using StartTLS
if ($startTlsMode === TLS_OPTIONAL && !$tlsOk) {
$ldap = connectAndSetOptions();
$tlsOk = true;
}
// TLS successful or not necessary, proceed with binding
if ($tlsOk) {
$bindOK = ldap_bind($ldap, 'cn=read-only-admin,dc=example,dc=com', 'password');
echo $bindOK ? 'Bind successful' : 'Bind failed';
} else {
echo 'No bind attempt';
}
function connectAndSetOptions() {
$ldap = ldap_connect('ldap://ldap.forumsys.com:389');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_TRY);
return $ldap;
}
Upvotes: 0