Many thanks for your prompt response and for pointing me at the appropriate
spec, Howard.

I don't believe that chaining and proxies are an option as I have no
control over the configuration of the LDAP server and must instead adapt
the client to accommodate servers that utilise referrals.

One alternative I've considered is:

1) Disable referral chasing in the client:

    ldap_set_option( ld , LDAP_OPT_REFERRALS , LDAP_OPT_OFF );


2) Bind to the top level server using master credentials.
3) Search for the specified user; if the user doesn't exist at that server,
one or more referrals will be returned.
4) Iterate over each referral attempting to bind to each one using the
user's credentials until either the bind succeeds or I run out of referral
candidates.

If you have time to comment on that proposal, I'd be very grateful.

Kind regards,
Mike


On Wed, 11 May 2022 at 22:57, Howard Chu <[email protected]> wrote:

> Mike Stevens wrote:
> > Good day.
> >
> >
> >
> > I’m an LDAP novice and am attempting to modify an LDAP client to
> accommodate an LDAP server environment that makes use of referrals.
> >
> >
> >
> > I have installed openLDAP 2.4.44 on 2 RHEL 7.9 servers.
> >
> >
> > The initial entries in the tree on serverA contains :
> >
> >
> > # xxx.com <http://xxx.com>
> > dn: dc=xxx,dc=com
> > description: xxx.com <http://xxx.com>
> > dc: xxx
> > o: xxx.com <http://xxx.com>
> > objectClass: top
> > objectClass: dcObject
> > objectClass: organization
> >
> > # Users, xxx.com <http://xxx.com>
> > dn: ou=Users,dc=xxx,dc=com
> > ou: Users
> > description: xxx Users
> > objectClass: organizationalUnit
> >
> > # search reference
> > *ref: ldap://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com??sub <
> http://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com??sub>*
> >
> > # mike, Users, xxx.com <http://xxx.com>
> > dn: uid=mike,ou=Users,dc=xxx,dc=com
> > cn: mike
> > ou: Users
> > uid: mike
> > givenName: Mike
> > mail: [email protected] <mailto:[email protected]>
> > objectClass: Person
> > objectClass: organizationalPerson
> > objectClass: inetOrgPerson
> >
> >
> >
> > I believe the "ref" entry is known as a subordinate referral;
> >
> > it was created by populating the tree from an LDIF file that contained
> the following:
> >
> >
> > dn: dc=uk,dc=xxx,dc=com
> > objectClass: referral
> > objectClass: extensibleObject
> > dc: uk
> > ref: ldap://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com <
> http://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com>
> >
> >
> > The intent is to redirect any requests received by serverA that refer to
> the subtree uk.xxx.com <http://uk.xxx.com> to serverB.
> >
> >
> > The tree on serverB contains:
> >
> >
> > # xxx.com <http://xxx.com>
> > dn: dc=xxx,dc=com
> > description: xxx.com <http://xxx.com>
> > dc: xxx
> > o: xxx.com <http://xxx.com>
> > objectClass: top
> > objectClass: dcObject
> > objectClass: organization
> >
> > # uk.xxx.com <http://uk.xxx.com>
> > dn: dc=uk,dc=xxx,dc=com
> > dc: uk
> > o: uk.xxx.com <http://uk.xxx.com>
> > description: xxx Users in the UK
> > objectClass: dcObject
> > objectClass: organization
> >
> > # mike, uk.xxx.com <http://uk.xxx.com>
> > dn: uid=mike,dc=uk,dc=xxx,dc=com
> > cn: mike
> > uid: mike
> > givenName: Mike
> > mail: [email protected] <mailto:[email protected]>
> > objectClass: person
> > objectClass: organizationalPerson
> > objectClass: inetOrgPerson
> >
> >
> > Now, if I perform a search on serverA specifying a base of uk.xxx.com <
> http://uk.xxx.com>, I get an RC=10 Referral result as expected:
> >
> > [root@serverA ~]# ldapsearch -x  '(uid=mike)' -b dc=uk,dc=xxx,dc=com
>  -LL
> > version: 1
> >
> > Referral (10)
> > Matched DN: dc=uk,dc=xxx,dc=com
> > Referral: ldap://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com??sub <
> http://serverB.xxx.com:389/dc=uk,dc=xxx,dc=com??sub>
> >
> > ... and I can chase that referral using the -C option to retrieve the
> entry from serverB:
> >
> > [root@Mike21 ~]# ldapsearch -x  '(uid=mike)' -b dc=uk,dc=ibm,dc=com
>  -LL -C
> > version: 1
> >
> > dn: uid=mike,dc=uk,dc=xxx,dc=com
> > cn: mike
> > uid: mike
> > givenName: Mike
> > mail: [email protected] <mailto:[email protected]>
> > objectClass: person
> > objectClass: organizationalPerson
> > objectClass: inetOrgPerson
> >
> > But, if I attempt a bind to serverA using the user that exists in
> serverB, I get an authentication failure:
> >
> > [root@serverA ~]# ldapsearch -x -b 'dc=uk,dc=xxx,dc=com' -D
> uid=mike,dc=uk,dc=xxx,dc=com -w passw0rD
> > ldap_bind: Invalid credentials (49)
> >
> > Now, I realise that the failure would be expected as the bind DN doesn't
> exist at serverA.
> > But I read that every request apart from unbind and abandon can result
> in a referral.
> > So why doesn't the bind follow the "ref" to serverB?
> > Is that possible and have I not configured my server correctly?
>
> No. See RFC3296 section 5.6.1.
> >
> > Ultimately, what I'd like to do in my client is something like:
> >
> >     ld_user = ldap_init( "ldap://serverA:389/dc=uk,dc=xxx,dc=com"; , 0 );
> >
> > ... followed by :
> >
> >    err = ldap_simple_bind_s( ld_user, "uid=mike,dc=uk,dc=xxx,dc=com" ,
> password);
> >
> > ... and have LDAP authenticate the given user against serverB based on
> the referral in serverA.
> >
> > Is this sort of set up possible?
>
> You will need to configure chaining or some other proxy mechanism instead.
> >
> > Many thanks for your advice,
> > Mike
> >
>
>
> --
>   -- Howard Chu
>   CTO, Symas Corp.           http://www.symas.com
>   Director, Highland Sun     http://highlandsun.com/hyc/
>   Chief Architect, OpenLDAP  http://www.openldap.org/project/
>

Reply via email to