Commit aa2fec0a authored by Peter Eisentraut's avatar Peter Eisentraut

Add support for LDAP URLs

Allow specifying LDAP authentication parameters as RFC 4516 LDAP URLs.
parent 26374f2a
...@@ -1486,6 +1486,34 @@ omicron bryanh guest1 ...@@ -1486,6 +1486,34 @@ omicron bryanh guest1
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>ldapurl</literal></term>
<listitem>
<para>
An RFC 4516 LDAP URL. This is an alternative way to write most of the
other LDAP options in a more compact and standard form. 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>
To use encrypted LDAP connections, the <literal>ldaptls</literal>
option has to be used in addition to <literal>ldapurl</literal>.
The <literal>ldaps</literal> URL scheme (direct SSL connection) is not
supported.
</para>
<para>
LDAP URLs are currently only supported with OpenLDAP, not on Windows.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
...@@ -1520,6 +1548,15 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse ...@@ -1520,6 +1548,15 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
If that second connection succeeds, the database access is granted. If that second connection succeeds, the database access is granted.
</para> </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>
Some other software that supports authentication against LDAP uses the
same URL format, so it will be easier to share the configuration.
</para>
<tip> <tip>
<para> <para>
Since LDAP often uses commas and spaces to separate the different Since LDAP often uses commas and spaces to separate the different
......
...@@ -2209,7 +2209,7 @@ CheckLDAPAuth(Port *port) ...@@ -2209,7 +2209,7 @@ CheckLDAPAuth(Port *port)
r = ldap_search_s(ldap, r = ldap_search_s(ldap,
port->hba->ldapbasedn, port->hba->ldapbasedn,
LDAP_SCOPE_SUBTREE, port->hba->ldapscope,
filter, filter,
attributes, attributes,
0, 0,
......
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#ifdef USE_LDAP
#ifndef WIN32
#include <ldap.h>
#endif
/* currently no Windows LDAP needed in this file */
#endif
#define atooid(x) ((Oid) strtoul((x), NULL, 10)) #define atooid(x) ((Oid) strtoul((x), NULL, 10))
#define atoxid(x) ((TransactionId) strtoul((x), NULL, 10)) #define atoxid(x) ((TransactionId) strtoul((x), NULL, 10))
...@@ -1336,7 +1343,7 @@ parse_hba_line(List *line, int line_num) ...@@ -1336,7 +1343,7 @@ parse_hba_line(List *line, int line_num)
{ {
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (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\"", errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName))); line_num, HbaFileName)));
return NULL; return NULL;
...@@ -1378,6 +1385,8 @@ parse_hba_line(List *line, int line_num) ...@@ -1378,6 +1385,8 @@ parse_hba_line(List *line, int line_num)
static bool static bool
parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
{ {
hbaline->ldapscope = LDAP_SCOPE_SUBTREE;
if (strcmp(name, "map") == 0) if (strcmp(name, "map") == 0)
{ {
if (hbaline->auth_method != uaIdent && if (hbaline->auth_method != uaIdent &&
...@@ -1437,6 +1446,54 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) ...@@ -1437,6 +1446,54 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam");
hbaline->pamservice = pstrdup(val); 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) else if (strcmp(name, "ldaptls") == 0)
{ {
REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap"); REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap");
......
...@@ -71,6 +71,7 @@ typedef struct HbaLine ...@@ -71,6 +71,7 @@ typedef struct HbaLine
char *ldapbindpasswd; char *ldapbindpasswd;
char *ldapsearchattribute; char *ldapsearchattribute;
char *ldapbasedn; char *ldapbasedn;
int ldapscope;
char *ldapprefix; char *ldapprefix;
char *ldapsuffix; char *ldapsuffix;
bool clientcert; bool clientcert;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment