Working on an EL7 system with PHP 5.6 and openldap 2.4.40.
I'm able to query the remote ldaps server using ldapsearch:
ldapsearch -H ldaps://ldap.example.com -D "CN=serviceaccount,OU=Services,DC=example,DC=com" -x -w "sapass" -LLL -b "DC=example,DC=com" cn="acoder"
This returns expected data on user acoder.
Moving to PHP, I'm attempting to bind to the same server using the same credentials and pass (sapass) above.
// server settings
$srvc_id = 'serviceaccount';
$srvc_pass = "somepass";
$ldap_host = "ldaps://ldap.example.com";
$srvc_dn = "CN=$srvc_id,OU=Services,DC=example,DC=com";
$user_filter = "(uid=$form_user)";
$ldap_conn = ldap_connect($ldap_host);
if ($ldap_conn)
{
echo "<p>Connected to \$ldap_host $ldap_host at line ";
$r = ldap_bind($ldap_conn, $srvc_dn, $srvc_pass);
if (!$r)
{
echo "<p>failed to bind with service account credentials.";
} else {
echo "<p>binded OK.";
}
}
If I temporarily add this to /etc/openldap/ldap.conf
, the script works:
TLS_REQCERT never
Once I comment that out, the script fails with "Can't contact LDAP server".
If I add TLS_CACERTDIR /etc/openldap/certs
to ldap.conf
, the script works fine when called from command line.
TLS_CACERTDIR /etc/openldap/certs
# TLS_REQCERT never ### only use for testing ###
It seems like httpd isn't reading a necessary certificate and is thus not able to communicate with the remote LDAP server.
The PHP/LDAP setup tutorials I've looked at work with EL6, and I am running EL7.
SOLVED!
SELinux is running Enforced. If I temporarily disabled SELinux, the ldap test script worked fine in a browser.
That led me to this helpful answer and this CentOS Wiki on SELinux. Here we learn:
SELinux doesn't allow your httpd daemon to talk to the LDAP server on the same machine.
Ah. It turns out SELinux has a multitude of fine-grained switches to allow specific activity from different processes. In my case, SELinux was configured out of the box to disallow LDAP connectivity (even though ldaps is enabled in firewalld).
You can check SELinux configuration of httpd using:
getsebool -a | grep httpd
which returns:
[acoder@myboxen]# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
To enable SELinux network connectivity through httpd:
setsebool -P httpd_can_network_connect on
No need to restart Apache. My ldap script worked fine from that moment on.
As above, be sure to remove TLS_REQCERT never
from your /etc/openldap/ldap.conf
and of course set SELinux back to Enforcing
with setenforce 1
.
Hope this is helpful to others.