Add support for LDAP URLs
Allow specifying LDAP authentication parameters as RFC 4516 LDAP URLs.
This commit is contained in:
parent
26374f2a0f
commit
aa2fec0a18
@ -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
|
|||||||
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)
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user