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

Commit6655c07

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 parentdb951dd commit6655c07

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
@@ -799,7 +799,7 @@ testdb=>
799799
</varlistentry>
800800

801801
<varlistentry>
802-
<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>
802+
<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>
803803
<listitem>
804804
<para>
805805
Establishes a new connection to a <productname>PostgreSQL</>
@@ -809,16 +809,19 @@ testdb=&gt;
809809
</para>
810810

811811
<para>
812-
When using positional parameters, if any of
813-
<replaceable class="parameter">dbname</replaceable>,
812+
Where the command omits database name, user, host, or port, the new
813+
connection can reuse values from the previous connection. By default,
814+
values from the previous connection are reused except when processing
815+
a <literal>conninfo</> string. Passing a first argument
816+
of <literal>-reuse-previous=on</>
817+
or <literal>-reuse-previous=off</literal> overrides that default.
818+
When the command neither specifies nor reuses a particular parameter,
819+
the <application>libpq</application> default is used. Specifying any
820+
of <replaceable class="parameter">dbname</replaceable>,
814821
<replaceable class="parameter">username</replaceable>,
815822
<replaceable class="parameter">host</replaceable> or
816-
<replaceable class="parameter">port</replaceable> are omitted or
817-
specified as <literal>-</literal>, the value of that parameter from
818-
the previous connection is used; if there is no previous connection,
819-
the <application>libpq</application> default for the parameter's value
820-
is used. When using <literal>conninfo</> strings, no values from the
821-
previous connection are used for the new connection.
823+
<replaceable class="parameter">port</replaceable>
824+
as <literal>-</literal> is equivalent to omitting that parameter.
822825
</para>
823826

824827
<para>

‎src/bin/psql/command.c

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ static backslashResult exec_command(const char *cmd,
5656
PQExpBufferquery_buf);
5757
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
5858
intlineno,bool*edited);
59-
staticbooldo_connect(char*dbname,char*user,char*host,char*port);
59+
staticbooldo_connect(enumtrivaluereuse_previous_specification,
60+
char*dbname,char*user,char*host,char*port);
6061
staticbooldo_shell(constchar*command);
6162
staticbooldo_watch(PQExpBufferquery_buf,longsleep);
6263
staticboollookup_function_oid(constchar*desc,Oid*foid);
@@ -217,12 +218,9 @@ exec_command(const char *cmd,
217218
/*
218219
* \c or \connect -- connect to database using the specified parameters.
219220
*
220-
* \c dbname user host port
221+
* \c[-reuse-previous=BOOL]dbname user host port
221222
*
222-
* If any of these parameters are omitted or specified as '-', the current
223-
* value of the parameter will be used instead. If the parameter has no
224-
* current value, the default value for that parameter will be used. Some
225-
* examples:
223+
* Specifying a parameter as '-' is equivalent to omitting it. Examples:
226224
*
227225
* \c - - hstConnect to current database on current port of host
228226
* "hst" as current user. \c - usr - prt Connect to current database on
@@ -231,17 +229,31 @@ exec_command(const char *cmd,
231229
*/
232230
elseif (strcmp(cmd,"c")==0||strcmp(cmd,"connect")==0)
233231
{
232+
staticconstcharprefix[]="-reuse-previous=";
234233
char*opt1,
235234
*opt2,
236235
*opt3,
237236
*opt4;
237+
enumtrivaluereuse_previous;
238238

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

244-
success=do_connect(opt1,opt2,opt3,opt4);
256+
success=do_connect(reuse_previous,opt1,opt2,opt3,opt4);
245257

246258
free(opt1);
247259
free(opt2);
@@ -1599,22 +1611,25 @@ param_is_newly_set(const char *old_val, const char *new_val)
15991611
/*
16001612
* do_connect -- handler for \connect
16011613
*
1602-
* Connects to a database with given parameters. If there exists an
1603-
* established connection, NULL values will be replaced with the ones
1604-
* in the current connection. Otherwise NULL will be passed for that
1605-
* parameter to PQconnectdbParams(), so the libpq defaults will be used.
1614+
* Connects to a database with given parameters. Absent an established
1615+
* connection, all parameters are required. Given -reuse-previous=off or a
1616+
* connection string without -reuse-previous=on, NULL values will pass through
1617+
* to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
1618+
* values will be replaced with the ones in the current connection.
16061619
*
16071620
* In interactive mode, if connection fails with the given parameters,
16081621
* the old connection will be kept.
16091622
*/
16101623
staticbool
1611-
do_connect(char*dbname,char*user,char*host,char*port)
1624+
do_connect(enumtrivaluereuse_previous_specification,
1625+
char*dbname,char*user,char*host,char*port)
16121626
{
16131627
PGconn*o_conn=pset.db,
16141628
*n_conn;
16151629
char*password=NULL;
16161630
boolkeep_password;
16171631
boolhas_connection_string;
1632+
boolreuse_previous;
16181633

16191634
if (!o_conn&& (!dbname|| !user|| !host|| !port))
16201635
{
@@ -1628,17 +1643,36 @@ do_connect(char *dbname, char *user, char *host, char *port)
16281643
return false;
16291644
}
16301645

1631-
/* grab values from the old connection, unless supplied by caller */
1632-
if (!user)
1646+
has_connection_string=dbname ?
1647+
recognized_connection_string(dbname) : false;
1648+
switch (reuse_previous_specification)
1649+
{
1650+
caseTRI_YES:
1651+
reuse_previous= true;
1652+
break;
1653+
caseTRI_NO:
1654+
reuse_previous= false;
1655+
break;
1656+
default:
1657+
reuse_previous= !has_connection_string;
1658+
break;
1659+
}
1660+
/* Silently ignore arguments subsequent to a connection string. */
1661+
if (has_connection_string)
1662+
{
1663+
user=NULL;
1664+
host=NULL;
1665+
port=NULL;
1666+
}
1667+
1668+
/* grab missing values from the old connection */
1669+
if (!user&&reuse_previous)
16331670
user=PQuser(o_conn);
1634-
if (!host)
1671+
if (!host&&reuse_previous)
16351672
host=PQhost(o_conn);
1636-
if (!port)
1673+
if (!port&&reuse_previous)
16371674
port=PQport(o_conn);
16381675

1639-
has_connection_string=
1640-
dbname ?recognized_connection_string(dbname) : false;
1641-
16421676
/*
16431677
* Any change in the parameters read above makes us discard the password.
16441678
* We also discard it if we're to use a conninfo rather than the
@@ -1655,10 +1689,10 @@ do_connect(char *dbname, char *user, char *host, char *port)
16551689
(port&&PQport(o_conn)&&strcmp(port,PQport(o_conn))==0);
16561690

16571691
/*
1658-
* Grab dbname from old connection unless supplied by caller. No password
1659-
*discard if thischanges: passwords aren't (usually) database-specific.
1692+
* Grabmissingdbname from old connection. No password discard if this
1693+
* changes: passwords aren't (usually) database-specific.
16601694
*/
1661-
if (!dbname)
1695+
if (!dbname&&reuse_previous)
16621696
dbname=PQdb(o_conn);
16631697

16641698
/*
@@ -1689,20 +1723,27 @@ do_connect(char *dbname, char *user, char *host, char *port)
16891723
#definePARAMS_ARRAY_SIZE8
16901724
constchar**keywords=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*keywords));
16911725
constchar**values=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*values));
1692-
intparamnum=0;
1726+
intparamnum=-1;
16931727

1694-
keywords[0]="dbname";
1695-
values[0]=dbname;
1728+
keywords[++paramnum]="host";
1729+
values[paramnum]=host;
1730+
keywords[++paramnum]="port";
1731+
values[paramnum]=port;
1732+
keywords[++paramnum]="user";
1733+
values[paramnum]=user;
16961734

1697-
if (!has_connection_string)
1698-
{
1699-
keywords[++paramnum]="host";
1700-
values[paramnum]=host;
1701-
keywords[++paramnum]="port";
1702-
values[paramnum]=port;
1703-
keywords[++paramnum]="user";
1704-
values[paramnum]=user;
1705-
}
1735+
/*
1736+
* Position in the array matters when the dbname is a connection
1737+
* string, because settings in a connection string override earlier
1738+
* array entries only. Thus, user= in the connection string always
1739+
* takes effect, but client_encoding= often will not.
1740+
*
1741+
* If you change this code, also change the initial-connection code in
1742+
* main(). For no good reason, a connection string password= takes
1743+
* precedence in main() but not here.
1744+
*/
1745+
keywords[++paramnum]="dbname";
1746+
values[paramnum]=dbname;
17061747
keywords[++paramnum]="password";
17071748
values[paramnum]=password;
17081749
keywords[++paramnum]="fallback_application_name";

‎src/bin/psql/startup.c

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp