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

Commitdfb2d80

Browse files
committed
Introduce a psql "\connect -reuse-previous=on|off" option.
The decision to reuse values of parameters from a previous connectionhas been based on whether the new target is a conninfo string. Add thismeans of overriding that default. This feature arose as one componentof a fix for security vulnerabilities in pg_dump, pg_dumpall, andpg_upgrade, so back-patch to 9.1 (all supported versions). In 9.3 andlater, comment paragraphs that required update had already-incorrectclaims about behavior when no connection is open; fix those problems.Security:CVE-2016-5424
1 parenta44d713 commitdfb2d80

File tree

3 files changed

+88
-44
lines changed

3 files changed

+88
-44
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ testdb=>
775775
</varlistentry>
776776

777777
<varlistentry>
778-
<term><literal>\c</literal> or <literal>\connect</literal> <literal>[ <replaceable class="parameter">dbname</replaceable> [ <replaceable class="parameter">username</replaceable> ] [ <replaceable class="parameter">host</replaceable> ] [ <replaceable class="parameter">port</replaceable> ]]| <replaceable class="parameter">conninfo</replaceable> </literal></term>
778+
<term><literal>\c</literal> or <literal>\connect [ -reuse-previous=<replaceable class="parameter">on|off</replaceable> ][ <replaceable class="parameter">dbname</replaceable> [ <replaceable class="parameter">username</replaceable> ] [ <replaceable class="parameter">host</replaceable> ] [ <replaceable class="parameter">port</replaceable> ] | <replaceable class="parameter">conninfo</replaceable>]</literal></term>
779779
<listitem>
780780
<para>
781781
Establishes a new connection to a <productname>PostgreSQL</>
@@ -785,16 +785,19 @@ testdb=&gt;
785785
</para>
786786

787787
<para>
788-
When using positional parameters, if any of
789-
<replaceable class="parameter">dbname</replaceable>,
788+
Where the command omits database name, user, host, or port, the new
789+
connection can reuse values from the previous connection. By default,
790+
values from the previous connection are reused except when processing
791+
a <literal>conninfo</> string. Passing a first argument
792+
of <literal>-reuse-previous=on</>
793+
or <literal>-reuse-previous=off</literal> overrides that default.
794+
When the command neither specifies nor reuses a particular parameter,
795+
the <application>libpq</application> default is used. Specifying any
796+
of <replaceable class="parameter">dbname</replaceable>,
790797
<replaceable class="parameter">username</replaceable>,
791798
<replaceable class="parameter">host</replaceable> or
792-
<replaceable class="parameter">port</replaceable> are omitted or
793-
specified as <literal>-</literal>, the value of that parameter from
794-
the previous connection is used; if there is no previous connection,
795-
the <application>libpq</application> default for the parameter's value
796-
is used. When using <literal>conninfo</> strings, no values from the
797-
previous connection are used for the new connection.
799+
<replaceable class="parameter">port</replaceable>
800+
as <literal>-</literal> is equivalent to omitting that parameter.
798801
</para>
799802

800803
<para>

‎src/bin/psql/command.c

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static backslashResult exec_command(const char *cmd,
5959
PQExpBufferquery_buf);
6060
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
6161
intlineno,bool*edited);
62-
staticbooldo_connect(char*dbname,char*user,char*host,char*port);
62+
staticbooldo_connect(enumtrivaluereuse_previous_specification,
63+
char*dbname,char*user,char*host,char*port);
6364
staticbooldo_shell(constchar*command);
6465
staticbooldo_watch(PQExpBufferquery_buf,longsleep);
6566
staticboollookup_function_oid(PGconn*conn,constchar*desc,Oid*foid);
@@ -218,12 +219,9 @@ exec_command(const char *cmd,
218219
/*
219220
* \c or \connect -- connect to database using the specified parameters.
220221
*
221-
* \c dbname user host port
222+
* \c[-reuse-previous=BOOL]dbname user host port
222223
*
223-
* If any of these parameters are omitted or specified as '-', the current
224-
* value of the parameter will be used instead. If the parameter has no
225-
* current value, the default value for that parameter will be used. Some
226-
* examples:
224+
* Specifying a parameter as '-' is equivalent to omitting it. Examples:
227225
*
228226
* \c - - hstConnect to current database on current port of host
229227
* "hst" as current user. \c - usr - prt Connect to current database on
@@ -232,17 +230,31 @@ exec_command(const char *cmd,
232230
*/
233231
elseif (strcmp(cmd,"c")==0||strcmp(cmd,"connect")==0)
234232
{
233+
staticconstcharprefix[]="-reuse-previous=";
235234
char*opt1,
236235
*opt2,
237236
*opt3,
238237
*opt4;
238+
enumtrivaluereuse_previous;
239239

240240
opt1=read_connect_arg(scan_state);
241+
if (opt1!=NULL&&strncmp(opt1,prefix,sizeof(prefix)-1)==0)
242+
{
243+
reuse_previous=
244+
ParseVariableBool(opt1+sizeof(prefix)-1,prefix) ?
245+
TRI_YES :TRI_NO;
246+
247+
free(opt1);
248+
opt1=read_connect_arg(scan_state);
249+
}
250+
else
251+
reuse_previous=TRI_DEFAULT;
252+
241253
opt2=read_connect_arg(scan_state);
242254
opt3=read_connect_arg(scan_state);
243255
opt4=read_connect_arg(scan_state);
244256

245-
success=do_connect(opt1,opt2,opt3,opt4);
257+
success=do_connect(reuse_previous,opt1,opt2,opt3,opt4);
246258

247259
free(opt1);
248260
free(opt2);
@@ -1545,22 +1557,25 @@ param_is_newly_set(const char *old_val, const char *new_val)
15451557
/*
15461558
* do_connect -- handler for \connect
15471559
*
1548-
* Connects to a database with given parameters. If there exists an
1549-
* established connection, NULL values will be replaced with the ones
1550-
* in the current connection. Otherwise NULL will be passed for that
1551-
* parameter to PQconnectdbParams(), so the libpq defaults will be used.
1560+
* Connects to a database with given parameters. Absent an established
1561+
* connection, all parameters are required. Given -reuse-previous=off or a
1562+
* connection string without -reuse-previous=on, NULL values will pass through
1563+
* to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
1564+
* values will be replaced with the ones in the current connection.
15521565
*
15531566
* In interactive mode, if connection fails with the given parameters,
15541567
* the old connection will be kept.
15551568
*/
15561569
staticbool
1557-
do_connect(char*dbname,char*user,char*host,char*port)
1570+
do_connect(enumtrivaluereuse_previous_specification,
1571+
char*dbname,char*user,char*host,char*port)
15581572
{
15591573
PGconn*o_conn=pset.db,
15601574
*n_conn;
15611575
char*password=NULL;
15621576
boolkeep_password;
15631577
boolhas_connection_string;
1578+
boolreuse_previous;
15641579

15651580
if (!o_conn&& (!dbname|| !user|| !host|| !port))
15661581
{
@@ -1574,17 +1589,36 @@ do_connect(char *dbname, char *user, char *host, char *port)
15741589
return false;
15751590
}
15761591

1577-
/* grab values from the old connection, unless supplied by caller */
1578-
if (!user)
1592+
has_connection_string=dbname ?
1593+
recognized_connection_string(dbname) : false;
1594+
switch (reuse_previous_specification)
1595+
{
1596+
caseTRI_YES:
1597+
reuse_previous= true;
1598+
break;
1599+
caseTRI_NO:
1600+
reuse_previous= false;
1601+
break;
1602+
default:
1603+
reuse_previous= !has_connection_string;
1604+
break;
1605+
}
1606+
/* Silently ignore arguments subsequent to a connection string. */
1607+
if (has_connection_string)
1608+
{
1609+
user=NULL;
1610+
host=NULL;
1611+
port=NULL;
1612+
}
1613+
1614+
/* grab missing values from the old connection */
1615+
if (!user&&reuse_previous)
15791616
user=PQuser(o_conn);
1580-
if (!host)
1617+
if (!host&&reuse_previous)
15811618
host=PQhost(o_conn);
1582-
if (!port)
1619+
if (!port&&reuse_previous)
15831620
port=PQport(o_conn);
15841621

1585-
has_connection_string=
1586-
dbname ?recognized_connection_string(dbname) : false;
1587-
15881622
/*
15891623
* Any change in the parameters read above makes us discard the password.
15901624
* We also discard it if we're to use a conninfo rather than the
@@ -1601,10 +1635,10 @@ do_connect(char *dbname, char *user, char *host, char *port)
16011635
(port&&PQport(o_conn)&&strcmp(port,PQport(o_conn))==0);
16021636

16031637
/*
1604-
* Grab dbname from old connection unless supplied by caller. No password
1605-
*discard if thischanges: passwords aren't (usually) database-specific.
1638+
* Grabmissingdbname from old connection. No password discard if this
1639+
* changes: passwords aren't (usually) database-specific.
16061640
*/
1607-
if (!dbname)
1641+
if (!dbname&&reuse_previous)
16081642
dbname=PQdb(o_conn);
16091643

16101644
/*
@@ -1635,20 +1669,27 @@ do_connect(char *dbname, char *user, char *host, char *port)
16351669
#definePARAMS_ARRAY_SIZE8
16361670
constchar**keywords=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*keywords));
16371671
constchar**values=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*values));
1638-
intparamnum=0;
1672+
intparamnum=-1;
16391673

1640-
keywords[0]="dbname";
1641-
values[0]=dbname;
1674+
keywords[++paramnum]="host";
1675+
values[paramnum]=host;
1676+
keywords[++paramnum]="port";
1677+
values[paramnum]=port;
1678+
keywords[++paramnum]="user";
1679+
values[paramnum]=user;
16421680

1643-
if (!has_connection_string)
1644-
{
1645-
keywords[++paramnum]="host";
1646-
values[paramnum]=host;
1647-
keywords[++paramnum]="port";
1648-
values[paramnum]=port;
1649-
keywords[++paramnum]="user";
1650-
values[paramnum]=user;
1651-
}
1681+
/*
1682+
* Position in the array matters when the dbname is a connection
1683+
* string, because settings in a connection string override earlier
1684+
* array entries only. Thus, user= in the connection string always
1685+
* takes effect, but client_encoding= often will not.
1686+
*
1687+
* If you change this code, also change the initial-connection code in
1688+
* main(). For no good reason, a connection string password= takes
1689+
* precedence in main() but not here.
1690+
*/
1691+
keywords[++paramnum]="dbname";
1692+
values[paramnum]=dbname;
16521693
keywords[++paramnum]="password";
16531694
values[paramnum]=password;
16541695
keywords[++paramnum]="fallback_application_name";

‎src/bin/psql/startup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ main(int argc, char *argv[])
210210
values[2]=options.username;
211211
keywords[3]="password";
212212
values[3]=password;
213-
keywords[4]="dbname";
213+
keywords[4]="dbname";/* see do_connect() */
214214
values[4]= (options.action==ACT_LIST_DB&&
215215
options.dbname==NULL) ?
216216
"postgres" :options.dbname;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp