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

Commitcae7ad9

Browse files
committed
Fix dblink_connect() so that it verifies that a password is supplied in the
conninfo string *before* trying to connect to the remote server, not after.As pointed out by Marko Kreen, in certain not-very-plausible situationsthis could result in sending a password from the postgres user's .pgpass file,or other places that non-superusers shouldn't have access to, to anuntrustworthy remote server. The cleanest fix seems to be to expose libpq'sconninfo-string-parsing code so that dblink can check for a password optionwithout duplicating the parsing logic.Joe Conway, with a little cleanup by Tom Lane
1 parent579c025 commitcae7ad9

File tree

6 files changed

+226
-50
lines changed

6 files changed

+226
-50
lines changed

‎contrib/dblink/dblink.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <Darko.Prenosil@finteh.hr>
99
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.74 2008/07/03 03:56:57 joe Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.75 2008/09/22 13:55:13 tgl Exp $
1212
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -93,6 +93,7 @@ static int16 get_attnum_pk_pos(int2vector *pkattnums, int16 pknumatts, int16 key
9393
staticHeapTupleget_tuple_of_interest(Oidrelid,int2vector*pkattnums,int16pknumatts,char**src_pkattvals);
9494
staticOidget_relid_from_relname(text*relname_text);
9595
staticchar*generate_relation_name(Oidrelid);
96+
staticvoiddblink_connstr_check(constchar*connstr);
9697
staticvoiddblink_security_check(PGconn*conn,remoteConn*rconn);
9798
staticvoiddblink_res_error(constchar*conname,PGresult*res,constchar*dblink_context_msg,boolfail);
9899

@@ -165,6 +166,7 @@ typedef struct remoteConnHashEnt
165166
else \
166167
{ \
167168
connstr = conname_or_str; \
169+
dblink_connstr_check(connstr); \
168170
conn = PQconnectdb(connstr); \
169171
if (PQstatus(conn) == CONNECTION_BAD) \
170172
{ \
@@ -229,6 +231,9 @@ dblink_connect(PG_FUNCTION_ARGS)
229231

230232
if (connname)
231233
rconn= (remoteConn*)palloc(sizeof(remoteConn));
234+
235+
/* check password in connection string if not superuser */
236+
dblink_connstr_check(connstr);
232237
conn=PQconnectdb(connstr);
233238

234239
MemoryContextSwitchTo(oldcontext);
@@ -246,7 +251,7 @@ dblink_connect(PG_FUNCTION_ARGS)
246251
errdetail("%s",msg)));
247252
}
248253

249-
/* check password used if not superuser */
254+
/* check passwordactuallyused if not superuser */
250255
dblink_security_check(conn,rconn);
251256

252257
if (connname)
@@ -2251,6 +2256,46 @@ dblink_security_check(PGconn *conn, remoteConn *rconn)
22512256
}
22522257
}
22532258

2259+
/*
2260+
* For non-superusers, insist that the connstr specify a password. This
2261+
* prevents a password from being picked up from .pgpass, a service file,
2262+
* the environment, etc. We don't want the postgres user's passwords
2263+
* to be accessible to non-superusers.
2264+
*/
2265+
staticvoid
2266+
dblink_connstr_check(constchar*connstr)
2267+
{
2268+
if (!superuser())
2269+
{
2270+
PQconninfoOption*options;
2271+
PQconninfoOption*option;
2272+
boolconnstr_gives_password= false;
2273+
2274+
options=PQconninfoParse(connstr,NULL);
2275+
if (options)
2276+
{
2277+
for (option=options;option->keyword!=NULL;option++)
2278+
{
2279+
if (strcmp(option->keyword,"password")==0)
2280+
{
2281+
if (option->val!=NULL&&option->val[0]!='\0')
2282+
{
2283+
connstr_gives_password= true;
2284+
break;
2285+
}
2286+
}
2287+
}
2288+
PQconninfoFree(options);
2289+
}
2290+
2291+
if (!connstr_gives_password)
2292+
ereport(ERROR,
2293+
(errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
2294+
errmsg("password is required"),
2295+
errdetail("Non-superusers must provide a password in the connection string.")));
2296+
}
2297+
}
2298+
22542299
staticvoid
22552300
dblink_res_error(constchar*conname,PGresult*res,constchar*dblink_context_msg,boolfail)
22562301
{

‎doc/src/sgml/dblink.sgml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/dblink.sgml,v 1.4 2008/04/04 16:57:21 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/dblink.sgml,v 1.5 2008/09/22 13:55:13 tgl Exp $ -->
22

33
<sect1 id="dblink">
44
<title>dblink</title>
@@ -140,12 +140,19 @@
140140
involve a password, then impersonation and subsequent escalation of
141141
privileges can occur, because the session will appear to have
142142
originated from the user as which the local <productname>PostgreSQL</>
143-
server runs. Therefore, <function>dblink_connect_u()</> is initially
143+
server runs. Also, even if the remote server does demand a password,
144+
it is possible for the password to be supplied from the server
145+
environment, such as a <filename>~/.pgpass</> file belonging to the
146+
server's user. This opens not only a risk of impersonation, but the
147+
possibility of exposing a password to an untrustworthy remote server.
148+
Therefore, <function>dblink_connect_u()</> is initially
144149
installed with all privileges revoked from <literal>PUBLIC</>,
145150
making it un-callable except by superusers. In some situations
146151
it may be appropriate to grant <literal>EXECUTE</> permission for
147152
<function>dblink_connect_u()</> to specific users who are considered
148-
trustworthy, but this should be done with care.
153+
trustworthy, but this should be done with care. It is also recommended
154+
that any <filename>~/.pgpass</> file belonging to the server's user
155+
<emphasis>not</> contain any records specifying a wildcard host name.
149156
</para>
150157

151158
<para>

‎doc/src/sgml/libpq.sgml

Lines changed: 104 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.263 2008/09/19 20:06:13 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.264 2008/09/22 13:55:13 tgl Exp $ -->
22

33
<chapter id="libpq">
44
<title><application>libpq</application> - C Library</title>
@@ -593,7 +593,7 @@ typedef struct
593593
char *compiled; /* Fallback compiled in default value */
594594
char *val; /* Option's current value, or NULL */
595595
char *label; /* Label for field in connect dialog */
596-
char *dispchar; /*Characterto display for this field
596+
char *dispchar; /*Indicates howto display this field
597597
in a connect dialog. Values are:
598598
"" Display entered value as is
599599
"*" Password field - hide value
@@ -624,6 +624,51 @@ typedef struct
624624
</listitem>
625625
</varlistentry>
626626

627+
<varlistentry>
628+
<term><function>PQconninfoParse</function><indexterm><primary>PQconninfoParse</></></term>
629+
<listitem>
630+
<para>
631+
Returns parsed connection options from the provided connection string.
632+
633+
<synopsis>
634+
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
635+
</synopsis>
636+
</para>
637+
638+
<para>
639+
Parses a connection string and returns the resulting options as an
640+
array; or returns NULL if there is a problem with the connection
641+
string. This can be used to determine
642+
the <function>PQconnectdb</function> options in the provided
643+
connection string. The return value points to an array of
644+
<structname>PQconninfoOption</structname> structures, which ends
645+
with an entry having a null <structfield>keyword</> pointer.
646+
</para>
647+
648+
<para>
649+
Note that only options explicitly specified in the string will have
650+
values set in the result array; no defaults are inserted.
651+
</para>
652+
653+
<para>
654+
If <literal>errmsg</> is not NULL, then <literal>*errmsg</> is set
655+
to NULL on success, else to a malloc'd error string explaining
656+
the problem. (It is also possible for <literal>*errmsg</> to be
657+
set to NULL even when NULL is returned; this indicates an out-of-memory
658+
situation.)
659+
</para>
660+
661+
<para>
662+
After processing the options array, free it by passing it to
663+
<function>PQconninfoFree</function>. If this is not done, some memory
664+
is leaked for each call to <function>PQconninfoParse</function>.
665+
Conversely, if an error occurs and <literal>errmsg</> is not NULL,
666+
be sure to free the error string using <function>PQfreemem</>.
667+
</para>
668+
669+
</listitem>
670+
</varlistentry>
671+
627672
<varlistentry>
628673
<term><function>PQfinish</function><indexterm><primary>PQfinish</></></term>
629674
<listitem>
@@ -2985,39 +3030,6 @@ typedef struct {
29853030
</para>
29863031
</listitem>
29873032
</varlistentry>
2988-
2989-
<varlistentry>
2990-
<term>
2991-
<function>PQfreemem</function>
2992-
<indexterm>
2993-
<primary>PQfreemem</primary>
2994-
</indexterm>
2995-
</term>
2996-
2997-
<listitem>
2998-
<para>
2999-
Frees memory allocated by <application>libpq</>.
3000-
<synopsis>
3001-
void PQfreemem(void *ptr);
3002-
</synopsis>
3003-
</para>
3004-
3005-
<para>
3006-
Frees memory allocated by <application>libpq</>, particularly
3007-
<function>PQescapeByteaConn</function>,
3008-
<function>PQescapeBytea</function>,
3009-
<function>PQunescapeBytea</function>,
3010-
and <function>PQnotifies</function>.
3011-
It is particularly important that this function, rather than
3012-
<function>free()</>, be used on Microsoft Windows. This is because
3013-
allocating memory in a DLL and releasing it in the application works
3014-
only if multithreaded/single-threaded, release/debug, and static/dynamic
3015-
flags are the same for the DLL and the application. On non-Microsoft
3016-
Windows platforms, this function is the same as the standard library
3017-
function <function>free()</>.
3018-
</para>
3019-
</listitem>
3020-
</varlistentry>
30213033
</variablelist>
30223034

30233035
</sect2>
@@ -4537,6 +4549,63 @@ char *pg_encoding_to_char(int <replaceable>encoding_id</replaceable>);
45374549
</para>
45384550

45394551
<variablelist>
4552+
<varlistentry>
4553+
<term>
4554+
<function>PQfreemem</function>
4555+
<indexterm>
4556+
<primary>PQfreemem</primary>
4557+
</indexterm>
4558+
</term>
4559+
4560+
<listitem>
4561+
<para>
4562+
Frees memory allocated by <application>libpq</>.
4563+
<synopsis>
4564+
void PQfreemem(void *ptr);
4565+
</synopsis>
4566+
</para>
4567+
4568+
<para>
4569+
Frees memory allocated by <application>libpq</>, particularly
4570+
<function>PQescapeByteaConn</function>,
4571+
<function>PQescapeBytea</function>,
4572+
<function>PQunescapeBytea</function>,
4573+
and <function>PQnotifies</function>.
4574+
It is particularly important that this function, rather than
4575+
<function>free()</>, be used on Microsoft Windows. This is because
4576+
allocating memory in a DLL and releasing it in the application works
4577+
only if multithreaded/single-threaded, release/debug, and static/dynamic
4578+
flags are the same for the DLL and the application. On non-Microsoft
4579+
Windows platforms, this function is the same as the standard library
4580+
function <function>free()</>.
4581+
</para>
4582+
</listitem>
4583+
</varlistentry>
4584+
4585+
<varlistentry>
4586+
<term>
4587+
<function>PQconninfoFree</function>
4588+
<indexterm>
4589+
<primary>PQconninfoFree</primary>
4590+
</indexterm>
4591+
</term>
4592+
4593+
<listitem>
4594+
<para>
4595+
Frees the data structures allocated by
4596+
<function>PQconndefaults</> or <function>PQconninfoParse</>.
4597+
<synopsis>
4598+
void PQconninfoFree(PQconninfoOption *connOptions);
4599+
</synopsis>
4600+
</para>
4601+
4602+
<para>
4603+
A simple <function>PQfreemem</function> will not do for this, since
4604+
the array contains references to subsidiary strings.
4605+
</para>
4606+
</listitem>
4607+
</varlistentry>
4608+
45404609
<varlistentry>
45414610
<term>
45424611
<function>PQencryptPassword</function>

‎src/interfaces/libpq/exports.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.21 2008/09/19 20:06:13 tgl Exp $
1+
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.22 2008/09/22 13:55:14 tgl Exp $
22
# Functions to be exported by libpq DLLs
33
PQconnectdb 1
44
PQsetdbLogin 2
@@ -151,3 +151,4 @@ PQsetInstanceData 148
151151
PQresultInstanceData 149
152152
PQresultSetInstanceData 150
153153
PQfireResultCreateEvents 151
154+
PQconninfoParse 152

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp