Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfd18965

Browse files
committed
Diagnose incompatible OpenLDAP versions during build and test.
With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, PostgreSQLbackends can crash at exit. Raise a warning during "configure" based onthe compile-time OpenLDAP version number, and test the crash scenario inthe dblink test suite. Back-patch to 9.0 (all supported versions).
1 parent87c4232 commitfd18965

File tree

11 files changed

+216
-1
lines changed

11 files changed

+216
-1
lines changed

‎configure

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9477,6 +9477,17 @@ fi
94779477

94789478
fi
94799479

9480+
# PGAC_LDAP_SAFE
9481+
# --------------
9482+
# PostgreSQL sometimes loads libldap_r and plain libldap into the same
9483+
# process. Check for OpenLDAP versions known not to tolerate doing so; assume
9484+
# non-OpenLDAP implementations are safe. The dblink test suite exercises the
9485+
# hazardous interaction directly.
9486+
9487+
9488+
9489+
9490+
94809491
iftest"$with_ldap" = yes;then
94819492
iftest"$PORTNAME"!="win32";then
94829493
forac_headerin ldap.h
@@ -9493,6 +9504,47 @@ fi
94939504

94949505
done
94959506

9507+
{$as_echo"$as_me:${as_lineno-$LINENO}: checking for compatible LDAP implementation">&5
9508+
$as_echo_n"checking for compatible LDAP implementation...">&6; }
9509+
if${pgac_cv_ldap_safe+:}false;then:
9510+
$as_echo_n"(cached)">&6
9511+
else
9512+
cat confdefs.h -<<_ACEOF >conftest.$ac_ext
9513+
/* end confdefs.h. */
9514+
#include <ldap.h>
9515+
#if !defined(LDAP_VENDOR_VERSION) ||\
9516+
(defined(LDAP_API_FEATURE_X_OPENLDAP) &&\
9517+
LDAP_VENDOR_VERSION >= 20424 && LDAP_VENDOR_VERSION <= 20431)
9518+
choke me
9519+
#endif
9520+
int
9521+
main ()
9522+
{
9523+
9524+
;
9525+
return 0;
9526+
}
9527+
_ACEOF
9528+
if ac_fn_c_try_compile"$LINENO";then:
9529+
pgac_cv_ldap_safe=yes
9530+
else
9531+
pgac_cv_ldap_safe=no
9532+
fi
9533+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
9534+
fi
9535+
{$as_echo"$as_me:${as_lineno-$LINENO}: result:$pgac_cv_ldap_safe">&5
9536+
$as_echo"$pgac_cv_ldap_safe">&6; }
9537+
9538+
iftest"$pgac_cv_ldap_safe"!= yes;then
9539+
{$as_echo"$as_me:${as_lineno-$LINENO}: WARNING:
9540+
*** With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, each backend
9541+
*** process that loads libpq (via WAL receiver, dblink, or postgres_fdw) and
9542+
*** also uses LDAP will crash on exit.">&5
9543+
$as_echo"$as_me: WARNING:
9544+
*** With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, each backend
9545+
*** process that loads libpq (via WAL receiver, dblink, or postgres_fdw) and
9546+
*** also uses LDAP will crash on exit.">&2;}
9547+
fi
94969548
else
94979549
forac_headerin winldap.h
94989550
do:

‎configure.in

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,10 +1098,39 @@ if test "$with_libxslt" = yes ; then
10981098
AC_CHECK_HEADER(libxslt/xslt.h, [], [AC_MSG_ERROR([header file <libxslt/xslt.h> is required for XSLT support])])
10991099
fi
11001100

1101+
# PGAC_LDAP_SAFE
1102+
# --------------
1103+
# PostgreSQL sometimes loads libldap_r and plain libldap into the same
1104+
# process. Check for OpenLDAP versions known not to tolerate doing so; assume
1105+
# non-OpenLDAP implementations are safe. The dblink test suite exercises the
1106+
# hazardous interaction directly.
1107+
1108+
AC_DEFUN([PGAC_LDAP_SAFE],
1109+
[AC_CACHE_CHECK([for compatible LDAP implementation], [pgac_cv_ldap_safe],
1110+
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
1111+
[#include <ldap.h>
1112+
#if !defined(LDAP_VENDOR_VERSION) || \
1113+
(defined(LDAP_API_FEATURE_X_OPENLDAP) && \
1114+
LDAP_VENDOR_VERSION >= 20424 && LDAP_VENDOR_VERSION <= 20431)
1115+
choke me
1116+
#endif], [])],
1117+
[pgac_cv_ldap_safe=yes],
1118+
[pgac_cv_ldap_safe=no])])
1119+
1120+
if test "$pgac_cv_ldap_safe" != yes; then
1121+
AC_MSG_WARN([
1122+
*** With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, each backend
1123+
*** process that loads libpq (via WAL receiver, dblink, or postgres_fdw) and
1124+
*** also uses LDAP will crash on exit.])
1125+
fi])
1126+
1127+
1128+
11011129
if test "$with_ldap" = yes ; then
11021130
if test "$PORTNAME" != "win32"; then
11031131
AC_CHECK_HEADERS(ldap.h, [],
11041132
[AC_MSG_ERROR([header file <ldap.h> is required for LDAP])])
1133+
PGAC_LDAP_SAFE
11051134
else
11061135
AC_CHECK_HEADERS(winldap.h, [],
11071136
[AC_MSG_ERROR([header file <winldap.h> is required for LDAP])],

‎contrib/dblink/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ SHLIB_PREREQS = submake-libpq
99
EXTENSION = dblink
1010
DATA = dblink--1.1.sql dblink--1.0--1.1.sql dblink--unpackaged--1.0.sql
1111

12-
REGRESS = dblink
12+
REGRESS = paths dblink
13+
REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress
14+
EXTRA_CLEAN = sql/paths.sql expected/paths.out
1315

1416
# the db name is hard-coded in the tests
1517
overrideUSE_MODULE_DB =

‎contrib/dblink/expected/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/paths.out

‎contrib/dblink/expected/dblink.out

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,33 @@ SELECT *
103103
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
104104
WHERE t.a > 7;
105105
ERROR: connection not available
106+
-- The first-level connection's backend will crash on exit given OpenLDAP
107+
-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
108+
-- process terminates and the postmaster responds. If process termination
109+
-- entails writing a core dump, that can take awhile. Wait for the process to
110+
-- vanish. At that point, the postmaster has called waitpid() on the crashed
111+
-- process, and it will accept no new connections until it has reinitialized
112+
-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
113+
-- after the backend updates shared memory to reflect its impending exit.)
114+
DO $pl$
115+
DECLARE
116+
detail text;
117+
BEGIN
118+
PERFORM wait_pid(crash_pid)
119+
FROM dblink('dbname=contrib_regression', $$
120+
SELECT pg_backend_pid() FROM dblink(
121+
'service=test_ldap dbname=contrib_regression',
122+
-- This string concatenation is a hack to shoehorn a
123+
-- set_pgservicefile call into the SQL statement.
124+
'SELECT 1' || set_pgservicefile('pg_service.conf')
125+
) t(c int)
126+
$$) AS t(crash_pid int);
127+
EXCEPTION WHEN OTHERS THEN
128+
GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;
129+
-- Expected error in a non-LDAP build.
130+
IF NOT detail LIKE 'syntax error in service file%' THEN RAISE; END IF;
131+
END
132+
$pl$;
106133
-- create a persistent connection
107134
SELECT dblink_connect('dbname=contrib_regression');
108135
dblink_connect

‎contrib/dblink/input/paths.source

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Initialization that requires path substitution.
2+
3+
CREATE FUNCTION putenv(text)
4+
RETURNS void
5+
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
6+
LANGUAGE C STRICT;
7+
8+
CREATE FUNCTION wait_pid(int)
9+
RETURNS void
10+
AS '@libdir@/regress@DLSUFFIX@'
11+
LANGUAGE C STRICT;
12+
13+
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
14+
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;

‎contrib/dblink/output/paths.source

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- Initialization that requires path substitution.
2+
CREATE FUNCTION putenv(text)
3+
RETURNS void
4+
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
5+
LANGUAGE C STRICT;
6+
CREATE FUNCTION wait_pid(int)
7+
RETURNS void
8+
AS '@libdir@/regress@DLSUFFIX@'
9+
LANGUAGE C STRICT;
10+
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
11+
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;

‎contrib/dblink/pg_service.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# pg_service.conf for minimally exercising libpq use of LDAP.
2+
3+
# Having failed to reach an LDAP server, libpq essentially ignores the
4+
# "service=test_ldap" in its connection string. Contact the "discard"
5+
# service; the test works whether or not it answers.
6+
[test_ldap]
7+
ldap://127.0.0.1:9/base?attribute?one?filter

‎contrib/dblink/sql/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/paths.sql

‎contrib/dblink/sql/dblink.sql

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,34 @@ SELECT *
6565
FROM dblink('SELECT * FROM foo')AS t(aint, btext, ctext[])
6666
WHEREt.a>7;
6767

68+
-- The first-level connection's backend will crash on exit given OpenLDAP
69+
-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
70+
-- process terminates and the postmaster responds. If process termination
71+
-- entails writing a core dump, that can take awhile. Wait for the process to
72+
-- vanish. At that point, the postmaster has called waitpid() on the crashed
73+
-- process, and it will accept no new connections until it has reinitialized
74+
-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
75+
-- after the backend updates shared memory to reflect its impending exit.)
76+
DO $pl$
77+
DECLARE
78+
detailtext;
79+
BEGIN
80+
PERFORM wait_pid(crash_pid)
81+
FROM dblink('dbname=contrib_regression', $$
82+
SELECT pg_backend_pid()FROM dblink(
83+
'service=test_ldap dbname=contrib_regression',
84+
-- This string concatenation is a hack to shoehorn a
85+
-- set_pgservicefile call into the SQL statement.
86+
'SELECT 1'|| set_pgservicefile('pg_service.conf')
87+
) t(cint)
88+
$$)AS t(crash_pidint);
89+
EXCEPTION WHEN OTHERS THEN
90+
GET STACKED DIAGNOSTICS detail= PG_EXCEPTION_DETAIL;
91+
-- Expected error in a non-LDAP build.
92+
IF NOT detailLIKE'syntax error in service file%' THEN RAISE; END IF;
93+
END
94+
$pl$;
95+
6896
-- create a persistent connection
6997
SELECT dblink_connect('dbname=contrib_regression');
7098

‎src/test/regress/regress.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include<float.h>
88
#include<math.h>
9+
#include<signal.h>
910

1011
#include"access/htup_details.h"
1112
#include"access/transam.h"
@@ -16,6 +17,7 @@
1617
#include"commands/trigger.h"
1718
#include"executor/executor.h"
1819
#include"executor/spi.h"
20+
#include"miscadmin.h"
1921
#include"utils/builtins.h"
2022
#include"utils/geo_decls.h"
2123
#include"utils/rel.h"
@@ -822,3 +824,44 @@ make_tuple_indirect(PG_FUNCTION_ARGS)
822824
*/
823825
PG_RETURN_POINTER(newtup->t_data);
824826
}
827+
828+
PG_FUNCTION_INFO_V1(regress_putenv);
829+
830+
Datum
831+
regress_putenv(PG_FUNCTION_ARGS)
832+
{
833+
MemoryContextoldcontext;
834+
char*envbuf;
835+
836+
if (!superuser())
837+
elog(ERROR,"must be superuser to change environment variables");
838+
839+
oldcontext=MemoryContextSwitchTo(TopMemoryContext);
840+
envbuf=text_to_cstring((text*)PG_GETARG_POINTER(0));
841+
MemoryContextSwitchTo(oldcontext);
842+
843+
if (putenv(envbuf)!=0)
844+
elog(ERROR,"could not set environment variable: %m");
845+
846+
PG_RETURN_VOID();
847+
}
848+
849+
/* Sleep until no process has a given PID. */
850+
PG_FUNCTION_INFO_V1(wait_pid);
851+
852+
Datum
853+
wait_pid(PG_FUNCTION_ARGS)
854+
{
855+
intpid=PG_GETARG_INT32(0);
856+
857+
if (!superuser())
858+
elog(ERROR,"must be superuser to check PID liveness");
859+
860+
while (kill(pid,0)==0)
861+
pg_usleep(50000);
862+
863+
if (errno!=ESRCH)
864+
elog(ERROR,"could not check PID %d liveness: %m",pid);
865+
866+
PG_RETURN_VOID();
867+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp