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

Commit9d924e9

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 parent984e5be commit9d924e9

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
@@ -825,7 +825,7 @@ testdb=>
825825
</varlistentry>
826826

827827
<varlistentry>
828-
<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>
828+
<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>
829829
<listitem>
830830
<para>
831831
Establishes a new connection to a <productname>PostgreSQL</>
@@ -835,16 +835,19 @@ testdb=&gt;
835835
</para>
836836

837837
<para>
838-
When using positional parameters, if any of
839-
<replaceable class="parameter">dbname</replaceable>,
838+
Where the command omits database name, user, host, or port, the new
839+
connection can reuse values from the previous connection. By default,
840+
values from the previous connection are reused except when processing
841+
a <literal>conninfo</> string. Passing a first argument
842+
of <literal>-reuse-previous=on</>
843+
or <literal>-reuse-previous=off</literal> overrides that default.
844+
When the command neither specifies nor reuses a particular parameter,
845+
the <application>libpq</application> default is used. Specifying any
846+
of <replaceable class="parameter">dbname</replaceable>,
840847
<replaceable class="parameter">username</replaceable>,
841848
<replaceable class="parameter">host</replaceable> or
842-
<replaceable class="parameter">port</replaceable> are omitted or
843-
specified as <literal>-</literal>, the value of that parameter from
844-
the previous connection is used; if there is no previous connection,
845-
the <application>libpq</application> default for the parameter's value
846-
is used. When using <literal>conninfo</> strings, no values from the
847-
previous connection are used for the new connection.
849+
<replaceable class="parameter">port</replaceable>
850+
as <literal>-</literal> is equivalent to omitting that parameter.
848851
</para>
849852

850853
<para>

‎src/bin/psql/command.c

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ static backslashResult exec_command(const char *cmd,
6565
PQExpBufferquery_buf);
6666
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
6767
intlineno,bool*edited);
68-
staticbooldo_connect(char*dbname,char*user,char*host,char*port);
68+
staticbooldo_connect(enumtrivaluereuse_previous_specification,
69+
char*dbname,char*user,char*host,char*port);
6970
staticbooldo_shell(constchar*command);
7071
staticbooldo_watch(PQExpBufferquery_buf,doublesleep);
7172
staticboollookup_object_oid(EditableObjectTypeobj_type,constchar*desc,
@@ -231,12 +232,9 @@ exec_command(const char *cmd,
231232
/*
232233
* \c or \connect -- connect to database using the specified parameters.
233234
*
234-
* \c dbname user host port
235+
* \c[-reuse-previous=BOOL]dbname user host port
235236
*
236-
* If any of these parameters are omitted or specified as '-', the current
237-
* value of the parameter will be used instead. If the parameter has no
238-
* current value, the default value for that parameter will be used. Some
239-
* examples:
237+
* Specifying a parameter as '-' is equivalent to omitting it. Examples:
240238
*
241239
* \c - - hstConnect to current database on current port of host
242240
* "hst" as current user. \c - usr - prt Connect to current database on
@@ -245,17 +243,31 @@ exec_command(const char *cmd,
245243
*/
246244
elseif (strcmp(cmd,"c")==0||strcmp(cmd,"connect")==0)
247245
{
246+
staticconstcharprefix[]="-reuse-previous=";
248247
char*opt1,
249248
*opt2,
250249
*opt3,
251250
*opt4;
251+
enumtrivaluereuse_previous;
252252

253253
opt1=read_connect_arg(scan_state);
254+
if (opt1!=NULL&&strncmp(opt1,prefix,sizeof(prefix)-1)==0)
255+
{
256+
reuse_previous=
257+
ParseVariableBool(opt1+sizeof(prefix)-1,prefix) ?
258+
TRI_YES :TRI_NO;
259+
260+
free(opt1);
261+
opt1=read_connect_arg(scan_state);
262+
}
263+
else
264+
reuse_previous=TRI_DEFAULT;
265+
254266
opt2=read_connect_arg(scan_state);
255267
opt3=read_connect_arg(scan_state);
256268
opt4=read_connect_arg(scan_state);
257269

258-
success=do_connect(opt1,opt2,opt3,opt4);
270+
success=do_connect(reuse_previous,opt1,opt2,opt3,opt4);
259271

260272
free(opt1);
261273
free(opt2);
@@ -1754,22 +1766,25 @@ param_is_newly_set(const char *old_val, const char *new_val)
17541766
/*
17551767
* do_connect -- handler for \connect
17561768
*
1757-
* Connects to a database with given parameters. If there exists an
1758-
* established connection, NULL values will be replaced with the ones
1759-
* in the current connection. Otherwise NULL will be passed for that
1760-
* parameter to PQconnectdbParams(), so the libpq defaults will be used.
1769+
* Connects to a database with given parameters. Absent an established
1770+
* connection, all parameters are required. Given -reuse-previous=off or a
1771+
* connection string without -reuse-previous=on, NULL values will pass through
1772+
* to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
1773+
* values will be replaced with the ones in the current connection.
17611774
*
17621775
* In interactive mode, if connection fails with the given parameters,
17631776
* the old connection will be kept.
17641777
*/
17651778
staticbool
1766-
do_connect(char*dbname,char*user,char*host,char*port)
1779+
do_connect(enumtrivaluereuse_previous_specification,
1780+
char*dbname,char*user,char*host,char*port)
17671781
{
17681782
PGconn*o_conn=pset.db,
17691783
*n_conn;
17701784
char*password=NULL;
17711785
boolkeep_password;
17721786
boolhas_connection_string;
1787+
boolreuse_previous;
17731788

17741789
if (!o_conn&& (!dbname|| !user|| !host|| !port))
17751790
{
@@ -1783,17 +1798,36 @@ do_connect(char *dbname, char *user, char *host, char *port)
17831798
return false;
17841799
}
17851800

1786-
/* grab values from the old connection, unless supplied by caller */
1787-
if (!user)
1801+
has_connection_string=dbname ?
1802+
recognized_connection_string(dbname) : false;
1803+
switch (reuse_previous_specification)
1804+
{
1805+
caseTRI_YES:
1806+
reuse_previous= true;
1807+
break;
1808+
caseTRI_NO:
1809+
reuse_previous= false;
1810+
break;
1811+
default:
1812+
reuse_previous= !has_connection_string;
1813+
break;
1814+
}
1815+
/* Silently ignore arguments subsequent to a connection string. */
1816+
if (has_connection_string)
1817+
{
1818+
user=NULL;
1819+
host=NULL;
1820+
port=NULL;
1821+
}
1822+
1823+
/* grab missing values from the old connection */
1824+
if (!user&&reuse_previous)
17881825
user=PQuser(o_conn);
1789-
if (!host)
1826+
if (!host&&reuse_previous)
17901827
host=PQhost(o_conn);
1791-
if (!port)
1828+
if (!port&&reuse_previous)
17921829
port=PQport(o_conn);
17931830

1794-
has_connection_string=
1795-
dbname ?recognized_connection_string(dbname) : false;
1796-
17971831
/*
17981832
* Any change in the parameters read above makes us discard the password.
17991833
* We also discard it if we're to use a conninfo rather than the
@@ -1808,10 +1842,10 @@ do_connect(char *dbname, char *user, char *host, char *port)
18081842
(port&&PQport(o_conn)&&strcmp(port,PQport(o_conn))==0);
18091843

18101844
/*
1811-
* Grab dbname from old connection unless supplied by caller. No password
1812-
*discard if thischanges: passwords aren't (usually) database-specific.
1845+
* Grabmissingdbname from old connection. No password discard if this
1846+
* changes: passwords aren't (usually) database-specific.
18131847
*/
1814-
if (!dbname)
1848+
if (!dbname&&reuse_previous)
18151849
dbname=PQdb(o_conn);
18161850

18171851
/*
@@ -1842,20 +1876,27 @@ do_connect(char *dbname, char *user, char *host, char *port)
18421876
#definePARAMS_ARRAY_SIZE8
18431877
constchar**keywords=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*keywords));
18441878
constchar**values=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*values));
1845-
intparamnum=0;
1879+
intparamnum=-1;
18461880

1847-
keywords[0]="dbname";
1848-
values[0]=dbname;
1881+
keywords[++paramnum]="host";
1882+
values[paramnum]=host;
1883+
keywords[++paramnum]="port";
1884+
values[paramnum]=port;
1885+
keywords[++paramnum]="user";
1886+
values[paramnum]=user;
18491887

1850-
if (!has_connection_string)
1851-
{
1852-
keywords[++paramnum]="host";
1853-
values[paramnum]=host;
1854-
keywords[++paramnum]="port";
1855-
values[paramnum]=port;
1856-
keywords[++paramnum]="user";
1857-
values[paramnum]=user;
1858-
}
1888+
/*
1889+
* Position in the array matters when the dbname is a connection
1890+
* string, because settings in a connection string override earlier
1891+
* array entries only. Thus, user= in the connection string always
1892+
* takes effect, but client_encoding= often will not.
1893+
*
1894+
* If you change this code, also change the initial-connection code in
1895+
* main(). For no good reason, a connection string password= takes
1896+
* precedence in main() but not here.
1897+
*/
1898+
keywords[++paramnum]="dbname";
1899+
values[paramnum]=dbname;
18591900
keywords[++paramnum]="password";
18601901
values[paramnum]=password;
18611902
keywords[++paramnum]="fallback_application_name";

‎src/bin/psql/startup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ main(int argc, char *argv[])
227227
values[2]=options.username;
228228
keywords[3]="password";
229229
values[3]=password;
230-
keywords[4]="dbname";
230+
keywords[4]="dbname";/* see do_connect() */
231231
values[4]= (options.list_dbs&&options.dbname==NULL) ?
232232
"postgres" :options.dbname;
233233
keywords[5]="fallback_application_name";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp