Обсуждение: BUG #17083: [PATCH] PostgreSQL fails to build with OpenLDAP 2.5.x
The following bug has been logged on the website:
Bug reference: 17083
Logged by: Adrian Ho
Email address: ml+postgresql@03s.net
PostgreSQL version: 13.3
Operating system: Ubuntu 20.04.2 LTS
Description:
OpenLDAP 2.5 merged the `ldap_r` and `ldap` libraries, so all per-handle
routines are now thread-safe by default. However, the removal of `ldap_r`
results in the following `configure` error:
```
checking for ldap_bind in -lldap... yes
checking for ldap_simple_bind in -lldap_r... no
configure: error: library 'ldap_r' is required for LDAP
```
This patch therefore fixes and clarifies the LDAP library detection
logic, by first selecting on thread-safety requirements, then looking
for the appropriate libraries. The underlying assumption is that for a
pre-2.5 setup, both `ldap` and `ldap_r` libraries are installed, so it
should only fall back to (thread-safe) `ldap` in a 2.5.x installation.
diff --git a/configure.in b/configure.in
index 14a6be6..02ad260 100644
--- a/configure.in
+++ b/configure.in
@@ -1241,17 +1241,19 @@ fi
if test "$with_ldap" = yes ; then
_LIBS="$LIBS"
if test "$PORTNAME" != "win32"; then
- AC_CHECK_LIB(ldap, ldap_bind, [],
- [AC_MSG_ERROR([library 'ldap' is required for LDAP])],
- [$EXTRA_LDAP_LIBS])
- LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
if test "$enable_thread_safety" = yes; then
# on some platforms ldap_r fails to link without PTHREAD_LIBS
- AC_CHECK_LIB(ldap_r, ldap_simple_bind, [],
- [AC_MSG_ERROR([library 'ldap_r' is required for LDAP])],
+ # OpenLDAP 2.5 merged ldap_r with ldap
+ AC_SEARCH_LIBS(ldap_simple_bind, [ldap_r ldap], [],
+ [AC_MSG_ERROR([not found in any LDAP library])],
[$PTHREAD_CFLAGS $PTHREAD_LIBS $EXTRA_LDAP_LIBS])
- LDAP_LIBS_FE="-lldap_r $EXTRA_LDAP_LIBS"
+ LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
+ LDAP_LIBS_FE="${ac_lib:+-l}$ac_lib $EXTRA_LDAP_LIBS"
else
+ AC_CHECK_LIB(ldap, ldap_bind, [],
+ [AC_MSG_ERROR([library 'ldap' is required for LDAP])],
+ [$EXTRA_LDAP_LIBS])
+ LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
LDAP_LIBS_FE="-lldap $EXTRA_LDAP_LIBS"
fi
AC_CHECK_FUNCS([ldap_initialize])
PG Bug reporting form <noreply@postgresql.org> writes:
> OpenLDAP 2.5 merged the `ldap_r` and `ldap` libraries, so all per-handle
> routines are now thread-safe by default.
Hm, does 2.5 exist in the wild yet? I checked Fedora rawhide, which
is my usual go-to platform for bleeding-edge stuff, but they are still
at 2.4.58.
As for the patch itself, I'm wondering about
+ LDAP_LIBS_FE="${ac_lib:+-l}$ac_lib $EXTRA_LDAP_LIBS"
That seems undesirably intimate with the implementation details
of AC_SEARCH_LIBS. Surely there's a better way?
regards, tom lane
On 6/7/21 9:46 pm, Tom Lane wrote: > PG Bug reporting form <noreply@postgresql.org> writes: >> OpenLDAP 2.5 merged the `ldap_r` and `ldap` libraries, so all per-handle >> routines are now thread-safe by default. > > Hm, does 2.5 exist in the wild yet? I checked Fedora rawhide, which > is my usual go-to platform for bleeding-edge stuff, but they are still > at 2.4.58. Gentoo and some other distros have pushed 2.5.5 out: https://repology.org/project/openldap/badges. This patch actually grew out of fixing the Homebrew Linux PostgreSQL build: https://github.com/Homebrew/homebrew-core/pull/80643 > As for the patch itself, I'm wondering about > > + LDAP_LIBS_FE="${ac_lib:+-l}$ac_lib $EXTRA_LDAP_LIBS" > > That seems undesirably intimate with the implementation details > of AC_SEARCH_LIBS. Surely there's a better way? Hmmm, good point, my Autotools-fu is not very strong. I'll see if there's a blessed way of doing the above, otherwise I'll probably have to test each library separately in an AC_CHECK_LIB cascade instead. -- Best Regards, Adrian
Adrian Ho <ml+postgresql@03s.net> writes:
> On 6/7/21 9:46 pm, Tom Lane wrote:
>> As for the patch itself, I'm wondering about
>> + LDAP_LIBS_FE="${ac_lib:+-l}$ac_lib $EXTRA_LDAP_LIBS"
>> That seems undesirably intimate with the implementation details
>> of AC_SEARCH_LIBS. Surely there's a better way?
> Hmmm, good point, my Autotools-fu is not very strong. I'll see if
> there's a blessed way of doing the above, otherwise I'll probably have
> to test each library separately in an AC_CHECK_LIB cascade instead.
Looking at the Autoconf docs, what AC_SEARCH_LIBS is specified to do is
"Prepend `-lLIBRARY' to `LIBS' for the first library found to contain
FUNCTION". So I'd suggest
* Save contents of LIBS and set it to empty
* Run AC_SEARCH_LIBS
* LDAP_LIBS_FE="$LIBS $EXTRA_LDAP_LIBS"
* Restore LIBS
I think we have some instances of that pattern already.
regards, tom lane
On 6/7/21 10:47 pm, Tom Lane wrote:
> Looking at the Autoconf docs, what AC_SEARCH_LIBS is specified to do is
> "Prepend `-lLIBRARY' to `LIBS' for the first library found to contain
> FUNCTION". So I'd suggest
>
> * Save contents of LIBS and set it to empty
> * Run AC_SEARCH_LIBS
> * LDAP_LIBS_FE="$LIBS $EXTRA_LDAP_LIBS"
> * Restore LIBS
>
> I think we have some instances of that pattern already.
Thanks, Tom, that turned out to only require one additional line, since
$LIBS is already being saved and restored around that block:
diff --git a/configure.in b/configure.in
index 14a6be6..842d61b 100644
--- a/configure.in
+++ b/configure.in
@@ -1241,17 +1241,20 @@ fi
if test "$with_ldap" = yes ; then
_LIBS="$LIBS"
if test "$PORTNAME" != "win32"; then
- AC_CHECK_LIB(ldap, ldap_bind, [],
- [AC_MSG_ERROR([library 'ldap' is required for LDAP])],
- [$EXTRA_LDAP_LIBS])
- LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
if test "$enable_thread_safety" = yes; then
# on some platforms ldap_r fails to link without PTHREAD_LIBS
- AC_CHECK_LIB(ldap_r, ldap_simple_bind, [],
- [AC_MSG_ERROR([library 'ldap_r' is required for LDAP])],
+ # OpenLDAP 2.5 merged ldap_r with ldap
+ LIBS=""
+ AC_SEARCH_LIBS(ldap_simple_bind, [ldap_r ldap], [],
+ [AC_MSG_ERROR([not found in any LDAP library])],
[$PTHREAD_CFLAGS $PTHREAD_LIBS $EXTRA_LDAP_LIBS])
- LDAP_LIBS_FE="-lldap_r $EXTRA_LDAP_LIBS"
+ LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
+ LDAP_LIBS_FE="$LIBS $EXTRA_LDAP_LIBS"
else
+ AC_CHECK_LIB(ldap, ldap_bind, [],
+ [AC_MSG_ERROR([library 'ldap' is required for LDAP])],
+ [$EXTRA_LDAP_LIBS])
+ LDAP_LIBS_BE="-lldap $EXTRA_LDAP_LIBS"
LDAP_LIBS_FE="-lldap $EXTRA_LDAP_LIBS"
fi
AC_CHECK_FUNCS([ldap_initialize])
--
Best Regards,
Adrian
Adrian Ho <ml+postgresql@03s.net> writes:
> Thanks, Tom, that turned out to only require one additional line, since
> $LIBS is already being saved and restored around that block:
I poked at this a bit further and realized that it's got a showstopper
problem: in OpenLDAP 2.4, ldap_simple_bind() exists in both libldap.so
and libldap_r.so. Thus, if we were dealing with an installation that
does not have a thread-safe libldap, the patched configure would
incorrectly seize on libldap.so as being an acceptable substitute,
allowing weird hard-to-diagnose failures at runtime.
IOW, while it might look from our existing coding like there's something
about ldap_simple_bind() that is tied to reentrancy, there isn't. How
else can we determine whether an OpenLDAP library is reentrant, if we
can no longer depend on the _r suffix?
Maybe we can decide that in 2021 such situations no longer exist in
the wild, but I'm unsure.
regards, tom lane
> On 7 Jul 2021, at 18:57, Tom Lane <tgl@sss.pgh.pa.us> wrote: > > Adrian Ho <ml+postgresql@03s.net> writes: >> Thanks, Tom, that turned out to only require one additional line, since >> $LIBS is already being saved and restored around that block: > > I poked at this a bit further and realized that it's got a showstopper > problem: in OpenLDAP 2.4, ldap_simple_bind() exists in both libldap.so > and libldap_r.so. Thus, if we were dealing with an installation that > does not have a thread-safe libldap, the patched configure would > incorrectly seize on libldap.so as being an acceptable substitute, > allowing weird hard-to-diagnose failures at runtime. > > IOW, while it might look from our existing coding like there's something > about ldap_simple_bind() that is tied to reentrancy, there isn't. How > else can we determine whether an OpenLDAP library is reentrant, if we > can no longer depend on the _r suffix? Couldn't we add a version check to find if we have < 2.5 or >= 2.5, and adjust libs accordingly? Alternatively we could perhaps check for LDAP_API_FEATURE_X_OPENLDAP_REENTRANT which IIUC when set defines -lldap to be reentrant. -- Daniel Gustafsson https://vmware.com/
Michael Paquier <michael@paquier.xyz> writes:
> On Thu, Jul 08, 2021 at 09:53:11AM +0200, Daniel Gustafsson wrote:
>> Couldn't we add a version check to find if we have < 2.5 or >= 2.5, and adjust
>> libs accordingly? Alternatively we could perhaps check for
>> LDAP_API_FEATURE_X_OPENLDAP_REENTRANT which IIUC when set defines -lldap to be
>> reentrant.
> Would you fetch the version number directly from the library?
Yeah, that all sounds kind of fragile.
On investigation it seems that libldap_r has been around basically
forever. Even my second-oldest buildfarm animal prairiedog has got
it (indeed libldap.dylib and libldap_r.dylib are symlinks to
the same file on that platform ... hmm). My oldest animal gaur
is irrelevant to this discussion, because we don't support
--enable-thread-safety on it in the first place.
That being the case, I think we might be okay just going with the
solution in Adrian's last patch, ie use libldap_r if it's there
and otherwise assume that libldap is thread-safe. It looks
fairly unlikely that anyone will ever have an issue with that;
while if we complicate the configure probe, we might be introducing
new problems just from that.
regards, tom lane
> On 8 Jul 2021, at 21:55, Tom Lane <tgl@sss.pgh.pa.us> wrote: > That being the case, I think we might be okay just going with the > solution in Adrian's last patch, ie use libldap_r if it's there > and otherwise assume that libldap is thread-safe. It looks > fairly unlikely that anyone will ever have an issue with that; > while if we complicate the configure probe, we might be introducing > new problems just from that. Absolutely, in light of that I agree that's the best option. -- Daniel Gustafsson https://vmware.com/
Michael Paquier <michael@paquier.xyz> writes:
> On Thu, Jul 08, 2021 at 10:02:30PM +0200, Daniel Gustafsson wrote:
>> On 8 Jul 2021, at 21:55, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> That being the case, I think we might be okay just going with the
>>> solution in Adrian's last patch, ie use libldap_r if it's there
>>> and otherwise assume that libldap is thread-safe.
>> Absolutely, in light of that I agree that's the best option.
> +1.
Done that way.
regards, tom lane
Michael Paquier <michael@paquier.xyz> writes:
> On Fri, Jul 09, 2021 at 12:40:16PM -0400, Tom Lane wrote:
>> Done that way.
> This broke LDAPS, and the regression tests of src/test/ldap/. Elver
> is one animal complaining, but I am able to reproduce this failure on
> my own Debian laptop:
Oh, that's interesting. elver's failure seems to be because it's now
deciding it doesn't HAVE_LDAP_INITIALIZE. However, on my RHEL8 machine
the current configure coding is still finding ldap_initialize; so I'd
assumed this was something BSD-specific. If you're seeing it on Debian
then I'm really confused about what the problem is.
regards, tom lane
I wrote:
> Oh, that's interesting. elver's failure seems to be because it's now
> deciding it doesn't HAVE_LDAP_INITIALIZE. However, on my RHEL8 machine
> the current configure coding is still finding ldap_initialize;
... or not. I must have been seeing what I expected to see yesterday,
because when I check it again now, it isn't finding ldap_initialize.
Close inspection of the Autoconf manual reveals the problem:
AC_CHECK_LIB updates LIBS only as part of its *default* success
action, which the current coding isn't using for libldap_r.
So we arrive at the ldap_initialize test with neither library
in LIBS.
But we really ought to probe libldap not libldap_r for
ldap_initialize, because we use that only on the backend side.
So the right fix is to do that probe before we mess around
with libldap_r, which I've now done.
regards, tom lane