DNS SRV support for LDAP authentication

Поиск
Список
Период
Сортировка
Hello hackers,

Some people like to use DNS SRV records to advertise LDAP servers on
their network.  Microsoft Active Directory is usually (always?) set up
that way.  Here is a patch to allow our LDAP auth module to support
that kind of discovery.  It copies the convention of the OpenLDAP
command line tools: if you give it a URL that has no hostname, it'll
try to extract a domain name from the bind DN, and then ask your DNS
server for a SRV record for LDAP-over-TCP at that domain.  The
OpenLDAP version of libldap.so exports the magic to do that, so the
patch is very small (but the infrastructure set-up to test it is a bit
of a schlep, see below).  I'll add this to the next Commitfest.

Testing instructions for (paths and commands given for FreeBSD, adjust
as appropriate):

1.  Install BIND:

$ sudo pkg install bind99

2.  Define a new zone for testing, by adding the following to the end
of /usr/local/etc/namedb/named.conf:

===== 8< =====
zone "my.test.domain" {
        type master;
        file "/usr/local/etc/namedb/master/my.test.domain";
};
===== 8< =====


3.  Create that zone file in /usr/local/etc/namedb/master/my.test.domain:

===== 8< =====
$TTL    10
@       IN      SOA     ns.my.test.domain. admin.my.test.domain. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
        IN      NS      ns.my.test.domain.
ns.my.test.domain.      IN      A       127.0.0.1
my.test.domain.         IN      A       127.0.0.1
ldap-server.my.test.domain.             IN      A       127.0.0.1
_ldap._tcp.my.test.domain.      IN      SRV     0       0       389
 ldap-server
===== 8< =====

4.  Start up bind:

# service named onestart

5.  Confirm that SRV lookups find our record:

$ dig @localhost _ldap._tcp.my-domain.com SRV
...
;; ANSWER SECTION:
_ldap._tcp.my-domain.com. 10    IN      SRV     0 0 389
ldap-server.my-domain.com.

6.  Tell your system libraries to use this DNS server by temporarily
changing /etc/resolv.conf to say:

===== 8< =====
nameserver 127.0.0.1
===== 8< =====

7.  Confirm that the OpenLDAP tools can look that SRV record up:

$ ldapsearch -H 'ldap:///ou%3Dblah%2Cdc%3Dmy-domain%2Cdc%3Dcom'

(That's "ou=blah,dc=my-domain,dc=com" URL-encoded, from which
"my-domain.com" will be extracted.)  You should see that it's trying
to connect to ldap-server port 389, and you can stick 'x' on the end
of it to see what it looks like when it can't find a SRV record, as a
sanity check:

$ ldapsearch -H 'ldap:///ou%3Dblah%2Cdc%3Dmy-domain%2Cdc%3Dcomx'
DNS SRV: Could not turn domain=my-domain.comx into a hostlist

8.  Set up an LDAP server listening on localhost port 389, and create
a user, such that you can actually authenticate from PostgreSQL with
it.  Gory details omitted.  First test that you can log in with LDAP
authentication when using a pg_hba.conf line like this:

host all fred 127.0.0.1/32 ldap
ldapurl="ldap://ldap-server.my-domain.com/dc=my-domain,dc=com?cn?sub"

9.  Next apply the patch and verify that you can take out the hostname
and let it be discovered via DNS SRV:

host all fred 127.0.0.1/32 ldap ldapurl="ldap:///dc=my-domain,dc=com?cn?sub"

(You can stick some elog(LOG, ...) lines into
InitializeLDAPConnection() if you want to check that
ldap_domain2hostlist() is in fact finding the hostname and port.)

This is a first draft.  Not tested much yet.  I wonder if
HAVE_LDAP_INITIALIZE is a reasonable way to detact OpenLDAP.  The
documentation was written in about 7 seconds so probably needs work.
There is probably a Windowsy way to do this too but I didn't look into
that.

-- 
Thomas Munro
http://www.enterprisedb.com

Вложения

В списке pgsql-hackers по дате отправления: