Here is a patch to support RFC 2255 LDAP URLs in pg_hba.conf. So, instead of, say
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid you could write host ... ldap lapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" Apache and probably other software uses the same format, and it's easier to have a common format for all such configuration instead of having to translate the information provided by the LDAP admin into each software's particular configuration spellings. I'm using the OpenLDAP-provided URL parsing routine, which means this wouldn't be supported on Windows. But we already support different authentication settings on different platforms, so this didn't seem such a big problem.
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index d053fce..ba6523b 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -1486,6 +1486,39 @@ <title>LDAP Authentication</title> </para> </listitem> </varlistentry> + <varlistentry> + <term><literal>ldapurl</literal></term> + <listitem> + <para> + You can write most of the LDAP options alternatively using an RFC 2255 + LDAP URL. The format is +<synopsis> +ldap://[<replaceable>user</replaceable>[:<replaceable>password</replaceable>]@]<replaceable>host</replaceable>[:<replaceable>port</replaceable>]/<replaceable>basedn</replaceable>[?[<replaceable>attribute</replaceable>][?[<replaceable>scope</replaceable>]]] +</synopsis> + <replaceable>scope</replaceable> must be one + of <literal>base</literal>, <literal>one</literal>, <literal>sub</literal>, + typically the latter. Only one attribute is used, and some other + components of standard LDAP URLs such as filters and extensions are + not supported. + </para> + + <para> + If you want encrypted LDAP connections, you have to use + the <literal>ldaptls</literal> option in addition + to <literal>ldapurl</literal>. The <literal>ldaps</literal> URL + scheme (direct SSL connection) is not supported. + </para> + + <para> + Some other software that supports authentication against LDAP uses the + same URL format, so it will be easier to share the configuration. + </para> + + <para> + LDAP URLs are currently only supported with OpenLDAP, not on Windows. + </para> + </listitem> + </varlistentry> </variablelist> </para> @@ -1520,6 +1553,13 @@ <title>LDAP Authentication</title> If that second connection succeeds, the database access is granted. </para> + <para> + Here is the same search+bind configuration written as a URL: +<programlisting> +host ... ldap lapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" +</programlisting> + </para> + <tip> <para> Since LDAP often uses commas and spaces to separate the different diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index ca470e1..cc1140d 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -2209,7 +2209,7 @@ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, r = ldap_search_s(ldap, port->hba->ldapbasedn, - LDAP_SCOPE_SUBTREE, + port->hba->ldapscope, filter, attributes, 0, diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 7502e82..ba630a7 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -37,6 +37,16 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" +#ifdef USE_LDAP +#ifndef WIN32 +/* We use a deprecated function to keep the codepath the same as win32. */ +#define LDAP_DEPRECATED 1 +#include <ldap.h> +#else +#include <winldap.h> +#endif +#endif + #define atooid(x) ((Oid) strtoul((x), NULL, 10)) #define atoxid(x) ((TransactionId) strtoul((x), NULL, 10)) @@ -1336,7 +1346,7 @@ static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, { ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, or ldapsearchattribute together with ldapprefix"), + errmsg("cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); return NULL; @@ -1378,6 +1388,8 @@ static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) { + hbaline->ldapscope = LDAP_SCOPE_SUBTREE; + if (strcmp(name, "map") == 0) { if (hbaline->auth_method != uaIdent && @@ -1437,6 +1449,54 @@ static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); hbaline->pamservice = pstrdup(val); } + else if (strcmp(name, "ldapurl") == 0) + { + LDAPURLDesc *urldata; + int rc; + + REQUIRE_AUTH_OPTION(uaLDAP, "ldapurl", "ldap"); + +#ifdef LDAP_API_FEATURE_X_OPENLDAP + rc = ldap_url_parse(val, &urldata); + if (rc != LDAP_SUCCESS) + { + ereport(LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not parse LDAP URL \"%s\": %s", val, ldap_err2string(rc)))); + return false; + } + + if (strcmp(urldata->lud_scheme, "ldap") != 0) + { + ereport(LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("unsupported LDAP URL scheme: %s", urldata->lud_scheme))); + ldap_free_urldesc(urldata); + return false; + } + + hbaline->ldapserver = pstrdup(urldata->lud_host); + hbaline->ldapport = urldata->lud_port; + hbaline->ldapbasedn = pstrdup(urldata->lud_dn); + + if (urldata->lud_attrs) + hbaline->ldapsearchattribute = pstrdup(urldata->lud_attrs[0]); /* only use first one */ + hbaline->ldapscope = urldata->lud_scope; + if (urldata->lud_filter) + { + ereport(LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("filters not supported in LDAP URLs"))); + ldap_free_urldesc(urldata); + return false; + } + ldap_free_urldesc(urldata); +#else /* not OpenLDAP */ + ereport(LOG, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("LDAP URLs not supported on this platform"))); +#endif /* not OpenLDAP */ + } else if (strcmp(name, "ldaptls") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap"); diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 408d262..79a5dc6 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -71,6 +71,7 @@ typedef struct HbaLine char *ldapbindpasswd; char *ldapsearchattribute; char *ldapbasedn; + int ldapscope; char *ldapprefix; char *ldapsuffix; bool clientcert;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers