[PATCH] Add an ldapoption to disable chasing LDAP referrals
Hey All,
This patch request grew from this post (of mine) to pgsql-general:
/messages/by-id/CABUevEzouAe-g1_OejaGujjMem675DNYStwyBp4d_Wz6Om+fxA@mail.gmail.com
The patch adds another available LDAP option (ldapnochaseref) for
search+bind mode in the pg_hba.conf fil. If set to 1 (0 is default) then it
performs a ldap_set_option which disables chasing of any LDAP references
which are returned as part of the search LDIF.
I can think of two use cases for this:
1. (the case which spawned my email) A valid search is performed, but
for some reason a "ref:" with a non responsive LDAP server is returned as
well, which causes the authentication to time out (could be intermittent if
DNS round robin or similar is used and some of the LDAP servers are not
functioning / a packet dropping firewall is in the way).
2. (a case I found when testing with AD) A valid search is performed and
6 "ref:" entries are returned, which all must be chased before
authentication can succeed. Setting ldapnochaseref speeds up authentication
with no negative cost (assuming you understand your LDAP schema).
I think it's work noting that this setting seems to be the default for
ldapsearch on Linux these days.
Hopefully I found all the documentation that I was meant to update, let me
know if not though.
Cheers,
James Sewell
PostgreSQL Team Lead / Solutions Architect
_____________________________________
[image:
http://www.lisasoft.com/sites/lisasoft/files/u1/2013hieghtslogan_0.png]
Level 2, 50 Queen St,
Melbourne, VIC, 3000
P: 03 8370 8000 F: 03 8370 8099 W: www.lisasoft.com
--
------------------------------
The contents of this email are confidential and may be subject to legal or
professional privilege and copyright. No representation is made that this
email is free of viruses or other defects. If you have received this
communication in error, you may not copy or distribute any part of it or
otherwise disclose its contents to anyone. Please advise the sender of your
incorrect receipt of this correspondence.
Attachments:
pgsql_ldapnochaseref_v1.diffapplication/octet-stream; name=pgsql_ldapnochaseref_v1.diffDownload
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 9fc583c..a0f1e8d 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -1520,6 +1520,15 @@ ldap://<replaceable>host</replaceable>[:<replaceable>port</replaceable>]/<replac
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>ldapnochaseref</literal></term>
+ <listitem>
+ <para>
+ Set to 1 to disable chasing of any LDAP references which are returned
+ as part of the search.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 415b614..a9b2e5c 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2061,6 +2061,18 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
return STATUS_ERROR;
}
+ if (port->hba->ldapnochaseref)
+ {
+
+ if ((r = ldap_set_option(*ldap, LDAP_OPT_REFERRALS, LDAP_OPT_OFF)) != LDAP_SUCCESS)
+ {
+ ldap_unbind(*ldap);
+ ereport(LOG,
+ (errmsg("could not disable LDAP referral chasing: %s", ldap_err2string(r))));
+ return STATUS_ERROR;
+ }
+ }
+
if (port->hba->ldaptls)
{
#ifndef WIN32
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 91f6ced..54619a0 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1529,6 +1529,14 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
else
hbaline->ldaptls = false;
}
+ else if (strcmp(name, "ldapnochaseref") == 0)
+ {
+ REQUIRE_AUTH_OPTION(uaLDAP, "ldapnochaseref", "ldap");
+ if (strcmp(val, "1") == 0)
+ hbaline->ldapnochaseref = true;
+ else
+ hbaline->ldapnochaseref = false;
+ }
else if (strcmp(name, "ldapserver") == 0)
{
REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap");
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 73ae510..fe9e010 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -66,6 +66,7 @@ typedef struct HbaLine
char *usermap;
char *pamservice;
bool ldaptls;
+ bool ldapnochaseref;
char *ldapserver;
int ldapport;
char *ldapbinddn;
On 7/2/13 12:20 AM, James Sewell wrote:
Hey All,
This patch request grew from this post (of mine) to pgsql-general:
/messages/by-id/CABUevEzouAe-g1_OejaGujjMem675DNYStwyBp4d_Wz6Om+fxA@mail.gmail.com
The patch adds another available LDAP option (ldapnochaseref) for
search+bind mode in the pg_hba.conf fil. If set to 1 (0 is default) then
it performs a ldap_set_option which disables chasing of any LDAP
references which are returned as part of the search LDIF.
This appears to be the same as the "referrals" option in pam_ldap
(http://linux.die.net/man/5/pam_ldap). So it seems legitimate.
For consistency, I would name the option ldapreferrals={0|1}. I prefer
avoiding double negatives.
Do you know of a standard way to represent this option in an LDAP URL,
perhaps as an extension?
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hey Peter,
You are correct, it is the same as the referrals option in pam_ldap. It's
also the -C (sometimes -R - it seems ldapsearch options are pretty
non-standard) option in ldapsearch.
As far as I'm aware you can't pass this in an LDAP URL, primarily because
this never gets sent to the LDAP server. The server always returns an LDIF
with inline references, this just determines if you chase them client side
or just list them as is.
I could be missing something here, but using:
ldapreferrals={0|1}
Would require a three state type, as we need a way of not interfering with
the library defaults? To 'enable' the new behavior here using a boolean you
would need to set ldapreferrals=false - which with the normal way of
dealing with config booleans would alter the default behavior if the option
was not specified.
How do you feel about:
ldapdisablereferrals=(0|1)
Cheers,
James Sewell
James Sewell
PostgreSQL Team Lead / Solutions Architect
_____________________________________
[image:
http://www.lisasoft.com/sites/lisasoft/files/u1/2013hieghtslogan_0.png]
Level 2, 50 Queen St,
Melbourne, VIC, 3000
P: 03 8370 8000 F: 03 8370 8099 W: www.lisasoft.com
On Tue, Jul 2, 2013 at 10:46 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On 7/2/13 12:20 AM, James Sewell wrote:
Hey All,
This patch request grew from this post (of mine) to pgsql-general:
/messages/by-id/CABUevEzouAe-g1_OejaGujjMem675DNYStwyBp4d_Wz6Om+fxA@mail.gmail.com
The patch adds another available LDAP option (ldapnochaseref) for
search+bind mode in the pg_hba.conf fil. If set to 1 (0 is default) then
it performs a ldap_set_option which disables chasing of any LDAP
references which are returned as part of the search LDIF.This appears to be the same as the "referrals" option in pam_ldap
(http://linux.die.net/man/5/pam_ldap). So it seems legitimate.For consistency, I would name the option ldapreferrals={0|1}. I prefer
avoiding double negatives.Do you know of a standard way to represent this option in an LDAP URL,
perhaps as an extension?
--
------------------------------
The contents of this email are confidential and may be subject to legal or
professional privilege and copyright. No representation is made that this
email is free of viruses or other defects. If you have received this
communication in error, you may not copy or distribute any part of it or
otherwise disclose its contents to anyone. Please advise the sender of your
incorrect receipt of this correspondence.
Attachments:
On Wed, Jul 3, 2013 at 3:04 AM, James Sewell <james.sewell@lisasoft.com>wrote:
Hey Peter,
You are correct, it is the same as the referrals option in pam_ldap. It's
also the -C (sometimes -R - it seems ldapsearch options are pretty
non-standard) option in ldapsearch.As far as I'm aware you can't pass this in an LDAP URL, primarily because
this never gets sent to the LDAP server. The server always returns an LDIF
with inline references, this just determines if you chase them client side
or just list them as is.I could be missing something here, but using:
ldapreferrals={0|1}
Would require a three state type, as we need a way of not interfering with
the library defaults? To 'enable' the new behavior here using a boolean you
would need to set ldapreferrals=false - which with the normal way of
dealing with config booleans would alter the default behavior if the option
was not specified.How do you feel about:
ldapdisablereferrals=(0|1)
I agree with Peter that the negative thing is bad. l don't see the problem,
really. If you don't specify it, you rely on library defaults. If you do
specify it, we lock it to that setting. I don't see the need to
specifically have a setting to rely on library defaults - just remove it
from the line and you get that.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
Heya,
I see what you are saying, the problem as I see it is that the action we
are taking here is "disable chasing ldap referrals". If the name is
ldapreferrals and we use a boolean then setting it to 1 reads in a counter
intuitive manner:
"set ldapreferals=true to disable chasing LDAP referrals."
Perhaps you are fine with this though if it's documented? It does work in
the inverse way to pam_ldap, where setting to true enables referral
chasing. pam_ldap works like so:
not set : library default
set to 0 : disable referral chasing
set to 1 : enable referral chasing
The other option would be to have the default value (of the parameter) be
true and set the boolean to false to disable it. I can't find any other
examples of this though - I assume having a one off like this in the code
is a bad thing also?
I'm happy to let you guys decide.
Cheers,
James
James Sewell
PostgreSQL Team Lead / Solutions Architect
_____________________________________
[image:
http://www.lisasoft.com/sites/lisasoft/files/u1/2013hieghtslogan_0.png]
Level 2, 50 Queen St,
Melbourne, VIC, 3000
P: 03 8370 8000 F: 03 8370 8099 W: www.lisasoft.com
On Wed, Jul 3, 2013 at 6:12 PM, Magnus Hagander <magnus@hagander.net> wrote:
On Wed, Jul 3, 2013 at 3:04 AM, James Sewell <james.sewell@lisasoft.com>wrote:
Hey Peter,
You are correct, it is the same as the referrals option in pam_ldap.
It's also the -C (sometimes -R - it seems ldapsearch options are pretty
non-standard) option in ldapsearch.As far as I'm aware you can't pass this in an LDAP URL, primarily because
this never gets sent to the LDAP server. The server always returns an LDIF
with inline references, this just determines if you chase them client side
or just list them as is.I could be missing something here, but using:
ldapreferrals={0|1}
Would require a three state type, as we need a way of not interfering
with the library defaults? To 'enable' the new behavior here using a
boolean you would need to set ldapreferrals=false - which with the normal
way of dealing with config booleans would alter the default behavior if the
option was not specified.How do you feel about:
ldapdisablereferrals=(0|1)
I agree with Peter that the negative thing is bad. l don't see the
problem, really. If you don't specify it, you rely on library defaults. If
you do specify it, we lock it to that setting. I don't see the need to
specifically have a setting to rely on library defaults - just remove it
from the line and you get that.--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
--
------------------------------
The contents of this email are confidential and may be subject to legal or
professional privilege and copyright. No representation is made that this
email is free of viruses or other defects. If you have received this
communication in error, you may not copy or distribute any part of it or
otherwise disclose its contents to anyone. Please advise the sender of your
incorrect receipt of this correspondence.
Attachments:
On Thu, Jul 4, 2013 at 2:30 AM, James Sewell <james.sewell@lisasoft.com>wrote:
Heya,
I see what you are saying, the problem as I see it is that the action we
are taking here is "disable chasing ldap referrals". If the name is
ldapreferrals and we use a boolean then setting it to 1 reads in a counter
intuitive manner:
That assumes that the default in the ldap library is always going to be to
chase them. Does the standard somehow mandate that it should be?
"set ldapreferals=true to disable chasing LDAP referrals."
You'd obviously reverse the meaning as well. "set ldapreferals=false to
disable chasing LDAP referrals."
Perhaps you are fine with this though if it's documented? It does work in
the inverse way to pam_ldap, where setting to true enables referral
chasing. pam_ldap works like so:not set : library default
set to 0 : disable referral chasing
set to 1 : enable referral chasing
That is exactly what I'm suggesting it should do, and I'm pretty sure
that's what Peter suggested as well.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
Hey,
New patch attached. I've moved from using a boolean to an enum trivalue.
Let me know what you think.
Cheers,
James
James Sewell
PostgreSQL Team Lead / Solutions Architect
_____________________________________
[image:
http://www.lisasoft.com/sites/lisasoft/files/u1/2013hieghtslogan_0.png]
Level 2, 50 Queen St,
Melbourne, VIC, 3000
P: 03 8370 8000 F: 03 8370 8099 W: www.lisasoft.com
On Thu, Jul 4, 2013 at 8:23 PM, Magnus Hagander <magnus@hagander.net> wrote:
On Thu, Jul 4, 2013 at 2:30 AM, James Sewell <james.sewell@lisasoft.com>wrote:
Heya,
I see what you are saying, the problem as I see it is that the action we
are taking here is "disable chasing ldap referrals". If the name is
ldapreferrals and we use a boolean then setting it to 1 reads in a counter
intuitive manner:That assumes that the default in the ldap library is always going to be to
chase them. Does the standard somehow mandate that it should be?"set ldapreferals=true to disable chasing LDAP referrals."
You'd obviously reverse the meaning as well. "set ldapreferals=false to
disable chasing LDAP referrals."Perhaps you are fine with this though if it's documented? It does work in
the inverse way to pam_ldap, where setting to true enables referral
chasing. pam_ldap works like so:not set : library default
set to 0 : disable referral chasing
set to 1 : enable referral chasingThat is exactly what I'm suggesting it should do, and I'm pretty sure
that's what Peter suggested as well.--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
--
------------------------------
The contents of this email are confidential and may be subject to legal or
professional privilege and copyright. No representation is made that this
email is free of viruses or other defects. If you have received this
communication in error, you may not copy or distribute any part of it or
otherwise disclose its contents to anyone. Please advise the sender of your
incorrect receipt of this correspondence.
Attachments:
pgsql_ldapnochaseref_v1.2.diffapplication/octet-stream; name=pgsql_ldapnochaseref_v1.2.diffDownload
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 9fc583c..fc92ef9 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -1520,6 +1520,14 @@ ldap://<replaceable>host</replaceable>[:<replaceable>port</replaceable>]/<replac
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>ldapreferrals</literal></term>
+ <listitem>
+ <para>
+ Specifies if referrals are automatically chased. Set to 1 to enable chasing, 0 to disable chasing. The default behaviour is specifed by the LDAP client library.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 415b614..e289360 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2061,6 +2061,30 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
return STATUS_ERROR;
}
+ if (port->hba->ldapreferrals == TRI_YES)
+ {
+
+ if ((r = ldap_set_option(*ldap, LDAP_OPT_REFERRALS, LDAP_OPT_ON )) != LDAP_SUCCESS)
+ {
+ ldap_unbind(*ldap);
+ ereport(LOG,
+ (errmsg("Could not set LDAP referrals: %s", ldap_err2string(r))));
+ return STATUS_ERROR;
+ }
+ }
+
+ if (port->hba->ldapreferrals == TRI_NO)
+ {
+
+ if ((r = ldap_set_option(*ldap, LDAP_OPT_REFERRALS, LDAP_OPT_OFF )) != LDAP_SUCCESS)
+ {
+ ldap_unbind(*ldap);
+ ereport(LOG,
+ (errmsg("Could not set LDAP referrals: %s", ldap_err2string(r))));
+ return STATUS_ERROR;
+ }
+ }
+
if (port->hba->ldaptls)
{
#ifndef WIN32
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 91f6ced..149efeb 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1218,7 +1218,10 @@ parse_hba_line(List *line, int line_num, char *raw_line)
#endif
else if (strcmp(token->string, "ldap") == 0)
#ifdef USE_LDAP
+ {
parsedline->auth_method = uaLDAP;
+ parsedline->ldapreferrals = TRI_DEFAULT;
+ }
#else
unsupauth = "ldap";
#endif
@@ -1529,6 +1532,15 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
else
hbaline->ldaptls = false;
}
+ else if (strcmp(name, "ldapreferrals") == 0)
+ {
+ REQUIRE_AUTH_OPTION(uaLDAP, "ldapreferrals", "ldap");
+ if (strcmp(val, "1") == 0)
+ hbaline->ldapreferrals = TRI_YES;
+ else if (strcmp(val, "0") == 0)
+ hbaline->ldapreferrals = TRI_NO;
+
+ }
else if (strcmp(name, "ldapserver") == 0)
{
REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap");
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 73ae510..d7fe64b 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -50,6 +50,13 @@ typedef enum ConnType
ctHostNoSSL
} ConnType;
+enum trivalue
+{
+ TRI_DEFAULT,
+ TRI_NO,
+ TRI_YES
+};
+
typedef struct HbaLine
{
int linenumber;
@@ -66,6 +73,7 @@ typedef struct HbaLine
char *usermap;
char *pamservice;
bool ldaptls;
+ enum trivalue ldapreferrals;
char *ldapserver;
int ldapport;
char *ldapbinddn;
On Tue, Jul 9, 2013 at 3:33 AM, James Sewell <james.sewell@lisasoft.com>wrote:
Hey,
New patch attached. I've moved from using a boolean to an enum trivalue.
Let me know what you think.
Please add your patch at
https://commitfest.postgresql.org/action/commitfest_view?id=19 so it's not
missed in the next commitfest!
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
On Tue, 2013-07-09 at 11:33 +1000, James Sewell wrote:
New patch attached. I've moved from using a boolean to an enum
trivalue.
You have updated the documentation to say that the ldareferrals option
only applies in search+bind mode. But looking over the code I think it
applies in both modes. Check please.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 7/8/13 9:33 PM, James Sewell wrote:
New patch attached. I've moved from using a boolean to an enum trivalue.
When ldapreferrals is set to something other than "0" or "1" exactly, it
just ignores the option. That's not good, I think. It should probably
be an error.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hey All,
I had missed these emails, sorry.
The search+bind mode issue is one of documentation location, I have fixed
it by moving the section to the applied to both list. As the patch is to do
with post-auth response this is correct.
As far as the issue when something other than 0 or 1 is set I am happy
throw an error (although this doesn't seem to be how option such as LDAPTLS
work: 1 if 1 else 0). I assume I would use the ereport() function to do
this (using the second example from this page
http://www.postgresql.org/docs/9.2/static/error-message-reporting.html)?
Cheers,
James
James Sewell,
PostgreSQL Team Lead / Solutions Architect
______________________________________
Level 2, 50 Queen St, Melbourne VIC 3000
*P *(+61) 3 8370 8000 * **W* www.lisasoft.com *F *(+61) 3 8370 8099
On Thu, Sep 19, 2013 at 12:56 AM, Peter Eisentraut <peter_e@gmx.net> wrote:
On 7/8/13 9:33 PM, James Sewell wrote:
New patch attached. I've moved from using a boolean to an enum trivalue.
When ldapreferrals is set to something other than "0" or "1" exactly, it
just ignores the option. That's not good, I think. It should probably
be an error.
--
------------------------------
The contents of this email are confidential and may be subject to legal or
professional privilege and copyright. No representation is made that this
email is free of viruses or other defects. If you have received this
communication in error, you may not copy or distribute any part of it or
otherwise disclose its contents to anyone. Please advise the sender of your
incorrect receipt of this correspondence.
On Thu, 2013-10-17 at 13:49 +1100, James Sewell wrote:
The search+bind mode issue is one of documentation location, I have
fixed it by moving the section to the applied to both list. As the
patch is to do with post-auth response this is correct.
Makes sense.
As far as the issue when something other than 0 or 1 is set I am happy
throw an error (although this doesn't seem to be how option such as
LDAPTLS work: 1 if 1 else 0).
Right, that's how ldapreferrals ought to work as well.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers