I haven't looked in detail to your message (yet, as I'm short of time right now), but it seems that your patches make sense by themselves. I suggest you submit your message to the ITS <http://www.openldap.org/its>, uploading your patches according to instructions at <http://www.openldap.org/devel/contributing.html>.
p. > Hello. > > This is a kind of follow-up on my previous message "Trouble with > slapd-ldap in various scenarios (LdarErr: DSID-0C090627)" sent to > OpenLDAP-Technical. I did more research on topic including a code > debugging. I finally found the reason why it doesn't work and fixed the > code. > > 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. > > 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" > > > 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 dirrectly: > > =================================================================================================== > # | 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. > > 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. > > I attached unified diffs of changes I made to OpenLDAP (2.4.18) source > code to make it working (fix for back-relay/op.c was much more easier in > 2.4.15). > > It looks like everyone uses the identity assertion mechanism because it > make the above mentioned use cases working in certain configurations. > Unfortunately, it's not a solution for me to use identity assertion. > > Could someone confirm my findings? > > Martin Rubas > >
