Full_Name: Martin Rubas Version: 2.4.18, 2.4.15 OS: Windows, Linux/Ubuntu URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (195.113.184.10)
Hello.
I have to use slapd-ldap in "strong bind" mode which means that user binds using its own credentials and no identity assertion is performed. If slapd-ldap is the only module that is processing request then everything works fine. If slapd-ldap is processing an request forwarded from slapd-relay (with slapo-rwm) or request to database with slapo-translucent then the authentication problem occurs.
First detected in OpenLDAP 2.4.15 but still present in 2.4.18.
=== Test Setup ===
Let's suppose that we have remote LDAP server with disabled anonymous binding. It could be Active Directory or OpenLDAP with following configuration:
# --- config for remote server (remote.host.net) --- # [cut-off] command schema, slapd files & logs definitions # Load of modules: modulepath /usr/lib/ldap moduleload back_hdb.la
# VERY IMPORTANT: Disable anonymous binding disallow bind_anon
# Configuration Database database config rootdn "cn=admin,cn=config" rootpw secret
# realone.net - local Repository database hdb suffix "dc=realone,dc=net" rootdn "cn=admin,dc=realone,dc=net" rootpw secret directory /var/lib/slapd/realone.net index objectClass eq index cn eq index uid eq
Let's say there is a common content in database:
# --- Directory content (just an overview) --- dn: dc=realone,dc=net # top, domain dn: ou=people,dc=realone,dc=net # organizationalUnit dn: ou=groups,dc=realone,dc=net # organizationalUnit dn: cn=idassert,dc=realone,dc=net # simpleSecurityObject,organizationalRole dn: cn=admin,dc=realone,dc=net # same as above dn: uid=super.account,ou=people,dc=realone,dc=net # inetOrgPerson,posixAccount, shadowAccount dn: uid=power.account,ou=people,dc=realone,dc=net # same as above dn: uid=basic.account,ou=people,dc=realone,dc=net # same as above dn: cn=admins,ou=groups,dc=realone,dc=net # posixGroup dn: cn=users,ou=groups,dc=realone,dc=net # same as above
I want to use another OpenLDAP server that is configured with slapo-translucent:
# --- config for local server (trans.local.net) --- # [cut-off] command schema, slapd files & logs definitions
# Configuration Database database config rootdn "cn=admin,cn=config" rootpw secret
# realone.net - local database extending the remote one database bdb suffix "dc=realone,dc=net" directory ./database/realone.net index objectClass eq index cn eq index uid eq
overlay translucent uri ldap://remote.host.net:389/ chase-referrals true rebind-as-user true
... or with slapd-relay (this is probably very very very rare use case but I used it for debugging):
# --- config for local server (relay.local.net) --- # [cut-off] command schema, slapd files & logs definitions
# Configuration Database database config rootdn "cn=admin,cn=config" rootpw secret
# domain (forwarded to remote repository) database ldap suffix "dc=realone,dc=net" uri ldap://remote.host.net chase-referrals yes
# domain alias database relay suffix "dc=virtual,dc=net" relay "dc=realone,dc=net"
overlay rwm rwm-suffixmassage "dc=virtual,dc=net" "dc=realone,dc=net"
=== Test Cases ===
Now, we can do usual search: ldapsearch -x -w secret -h <host-D <bindDN-b <baseDN-s sub "(objectClass=inetOrgPerson)" dn displayName mail (in my environment I should receive 3 records below ou=people,dc=realone,dc=net).
But the story is getting interesting here. The command works only in cases that slapd-ldap is used directly:
=================================================================================================== # | Host | BindDN | BaseDN | Result --+-----------------+----------------------------+-------------------+----------------------------- 1 | remote.host.net | cn=admin,dc=realone,dc=net | dc=realone,dc=net | Success (3 records) --+-----------------+----------------------------+-------------------+----------------------------- 2 | trans.local.net | cn=admin,dc=realone,dc=net | dc=realone,dc=net | Failure: Anon.bind.n.allwd. --+-----------------+----------------------------+-------------------+----------------------------- 3 | relay.local.net | cn=admin,dc=realone,dc=net | dc=realone,dc=net | Success (3 records) --+-----------------+----------------------------+-------------------+----------------------------- 4 | relay.local.net | cn=admin,dc=realone,dc=net | dc=virtual,dc=net | Success (3 records) !!!! --+-----------------+----------------------------+-------------------+----------------------------- 5 | relay.local.net | cn=admin,dc=virtual,dc=net | dc=virtual,dc=net | Failure: Anon.bind.n.allwd. ===================================================================================================
The failures of case #2 and #5 are not expected because the connection to remote server is handled by slapd-ldap configured the same way like in case 3. The success in case #3 is correct (although I didn't expected it) and it was guide to solution. I noticed that each time the request fail the LDAP connection is correctly opened and bind request is successful. But the search request was processed using a new connection that was created for it and anonymous bind executed with failure.
=== Debugging ===
While debugging, I found that ldap_back_getconn() is called by ldap_back_bind() as well as ldap_back_search() request handlers. For operations other then op_bind it tests whether connection associated with Operation (op->o_hdr->oh_conn) was used for authentication in previous step. If slapd-ldap is NOT using identity assertion then it checks Operation using SLAP_IS_AUTHZ_BACKEND macro whether op->o_conn->c_authz_backend is not NULL and is equal to current backend.
This test works fine is the slapd-ldap backend is the only which processes the LDAP request because op->o_conn->c_authz_backend is set in the binding handler of the frontend module - fe_op_bind(). In this, case the test succeeds and connection created during the binding is used also for searching.
If the slapd-ldap module is used as nested module in slapo-translucent (case #2), then the fe_op_bind() sets variable op->o_conn->c_authz_backend to the backend extended by slapo-translucent. Macro SLAP_IS_AUTHZ_BACKEND returns false and a new LDAP connection is allocated causing failure due anonymouse binding.
If the slapd-ldap module is target for slapd-relay then it behaves similar way. In case #5 the bind request is forwarded to slapd-ldap but slapd-relay is associated with connection as the backend who did the bind (op->o_conn->c_authz_backend) and subsequent search request fails the same way like above.
The success in case #4 is a kind of singularity ;-) - bind request is forwarded directly from frontend to slapd-ldap and therefore op->o_conn->c_authz_backend is set correctly, the subsequent search request goes first to slapd-relay which forwards it to slapd-ldap but SLAP_IS_AUTHZ_BACKEND test succeeds.
=== Patches uploaded to ftp.openldap.org ===
mrubas@kerio.com-090917.slapd_back-relay_op.c.2_4_15.patch mrubas@kerio.com-090917.slapd_back-relay_op.c.2_4_18.patch mrubas@kerio.com-090917.slapd_overlays_translucent.c.2_4_18.patch
Note: There is probably a better way how to fix that. I guess, that fix to slapd-ldap binding handler would be more efficient but I didn't find the right place to add code assigning the auth. backend to connection.