Skip to content

Commit 640768c

Browse files
committed
Field conninfo strings throughout src/bin/scripts.
These programs nominally accepted conninfo strings, but they would proceed to use the original dbname parameter as though it were an unadorned database name. This caused "reindexdb dbname=foo" to issue an SQL command that always failed, and other programs printed a conninfo string in error messages that purported to print a database name. Fix both problems by using PQdb() to retrieve actual database names. Continue to print the full conninfo string when reporting a connection failure. It is informative there, and if the database name is the sole problem, the server-side error message will include the name. Beyond those user-visible fixes, this allows a subsequent commit to synthesize and use conninfo strings without that implementation detail leaking into messages. As a side effect, the "vacuuming database" message now appears after, not before, the connection attempt. Back-patch to 9.1 (all supported versions). Reviewed by Michael Paquier and Peter Eisentraut. Security: CVE-2016-5424
1 parent 6655c07 commit 640768c

File tree

5 files changed

+40
-42
lines changed

5 files changed

+40
-42
lines changed

src/bin/scripts/clusterdb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,10 @@ cluster_one_database(const char *dbname, bool verbose, const char *table,
209209
{
210210
if (table)
211211
fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"),
212-
progname, table, dbname, PQerrorMessage(conn));
212+
progname, table, PQdb(conn), PQerrorMessage(conn));
213213
else
214214
fprintf(stderr, _("%s: clustering of database \"%s\" failed: %s"),
215-
progname, dbname, PQerrorMessage(conn));
215+
progname, PQdb(conn), PQerrorMessage(conn));
216216
PQfinish(conn);
217217
exit(1);
218218
}

src/bin/scripts/createlang.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,10 @@ main(int argc, char *argv[])
192192
result = executeQuery(conn, sql.data, progname, echo);
193193
if (PQntuples(result) > 0)
194194
{
195-
PQfinish(conn);
196195
fprintf(stderr,
197196
_("%s: language \"%s\" is already installed in database \"%s\"\n"),
198-
progname, langname, dbname);
197+
progname, langname, PQdb(conn));
198+
PQfinish(conn);
199199
/* separate exit status for "already installed" */
200200
exit(2);
201201
}

src/bin/scripts/droplang.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ main(int argc, char *argv[])
199199
result = executeQuery(conn, sql.data, progname, echo);
200200
if (PQntuples(result) == 0)
201201
{
202-
PQfinish(conn);
203202
fprintf(stderr, _("%s: language \"%s\" is not installed in "
204203
"database \"%s\"\n"),
205-
progname, langname, dbname);
204+
progname, langname, PQdb(conn));
205+
PQfinish(conn);
206206
exit(1);
207207
}
208208
PQclear(result);

src/bin/scripts/reindexdb.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ main(int argc, char *argv[])
263263
* specified
264264
*/
265265
if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL)
266-
reindex_one_database(dbname, dbname, "DATABASE", host, port,
266+
reindex_one_database(NULL, dbname, "DATABASE", host, port,
267267
username, prompt_password, progname, echo, verbose);
268268
}
269269

@@ -280,6 +280,9 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
280280

281281
PGconn *conn;
282282

283+
conn = connectDatabase(dbname, host, port, username, prompt_password,
284+
progname, false, false);
285+
283286
initPQExpBuffer(&sql);
284287

285288
appendPQExpBufferStr(&sql, "REINDEX");
@@ -294,26 +297,23 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
294297
else if (strcmp(type, "SCHEMA") == 0)
295298
appendPQExpBuffer(&sql, " SCHEMA %s", name);
296299
else if (strcmp(type, "DATABASE") == 0)
297-
appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
300+
appendPQExpBuffer(&sql, " DATABASE %s", fmtId(PQdb(conn)));
298301
appendPQExpBufferChar(&sql, ';');
299302

300-
conn = connectDatabase(dbname, host, port, username, prompt_password,
301-
progname, false, false);
302-
303303
if (!executeMaintenanceCommand(conn, sql.data, echo))
304304
{
305305
if (strcmp(type, "TABLE") == 0)
306306
fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
307-
progname, name, dbname, PQerrorMessage(conn));
307+
progname, name, PQdb(conn), PQerrorMessage(conn));
308308
if (strcmp(type, "INDEX") == 0)
309309
fprintf(stderr, _("%s: reindexing of index \"%s\" in database \"%s\" failed: %s"),
310-
progname, name, dbname, PQerrorMessage(conn));
310+
progname, name, PQdb(conn), PQerrorMessage(conn));
311311
if (strcmp(type, "SCHEMA") == 0)
312312
fprintf(stderr, _("%s: reindexing of schema \"%s\" in database \"%s\" failed: %s"),
313-
progname, name, dbname, PQerrorMessage(conn));
313+
progname, name, PQdb(conn), PQerrorMessage(conn));
314314
else
315315
fprintf(stderr, _("%s: reindexing of database \"%s\" failed: %s"),
316-
progname, dbname, PQerrorMessage(conn));
316+
progname, PQdb(conn), PQerrorMessage(conn));
317317
PQfinish(conn);
318318
exit(1);
319319
}
@@ -359,9 +359,11 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
359359
const char *username, enum trivalue prompt_password,
360360
const char *progname, bool echo, bool verbose)
361361
{
362+
PGconn *conn;
362363
PQExpBufferData sql;
363364

364-
PGconn *conn;
365+
conn = connectDatabase(dbname, host, port, username, prompt_password,
366+
progname, false, false);
365367

366368
initPQExpBuffer(&sql);
367369

@@ -370,10 +372,8 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
370372
if (verbose)
371373
appendPQExpBuffer(&sql, " (VERBOSE)");
372374

373-
appendPQExpBuffer(&sql, " SYSTEM %s;", dbname);
375+
appendPQExpBuffer(&sql, " SYSTEM %s;", PQdb(conn));
374376

375-
conn = connectDatabase(dbname, host, port, username, prompt_password,
376-
progname, false, false);
377377
if (!executeMaintenanceCommand(conn, sql.data, echo))
378378
{
379379
fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),

src/bin/scripts/vacuumdb.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,12 @@ static void prepare_vacuum_command(PQExpBuffer sql, PGconn *conn,
5757
vacuumingOptions *vacopts, const char *table);
5858

5959
static void run_vacuum_command(PGconn *conn, const char *sql, bool echo,
60-
const char *dbname, const char *table,
61-
const char *progname, bool async);
60+
const char *table, const char *progname, bool async);
6261

6362
static ParallelSlot *GetIdleSlot(ParallelSlot slots[], int numslots,
64-
const char *dbname, const char *progname);
63+
const char *progname);
6564

66-
static bool GetQueryResult(PGconn *conn, const char *dbname,
67-
const char *progname);
65+
static bool GetQueryResult(PGconn *conn, const char *progname);
6866

6967
static void DisconnectDatabase(ParallelSlot *slot);
7068

@@ -355,19 +353,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
355353
Assert(stage == ANALYZE_NO_STAGE ||
356354
(stage >= 0 && stage < ANALYZE_NUM_STAGES));
357355

356+
conn = connectDatabase(dbname, host, port, username, prompt_password,
357+
progname, false, true);
358+
358359
if (!quiet)
359360
{
360361
if (stage != ANALYZE_NO_STAGE)
361-
printf(_("%s: processing database \"%s\": %s\n"), progname, dbname,
362-
stage_messages[stage]);
362+
printf(_("%s: processing database \"%s\": %s\n"),
363+
progname, PQdb(conn), stage_messages[stage]);
363364
else
364-
printf(_("%s: vacuuming database \"%s\"\n"), progname, dbname);
365+
printf(_("%s: vacuuming database \"%s\"\n"),
366+
progname, PQdb(conn));
365367
fflush(stdout);
366368
}
367369

368-
conn = connectDatabase(dbname, host, port, username, prompt_password,
369-
progname, false, true);
370-
371370
initPQExpBuffer(&sql);
372371

373372
/*
@@ -473,7 +472,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
473472
* Get a free slot, waiting until one becomes free if none
474473
* currently is.
475474
*/
476-
free_slot = GetIdleSlot(slots, concurrentCons, dbname, progname);
475+
free_slot = GetIdleSlot(slots, concurrentCons, progname);
477476
if (!free_slot)
478477
{
479478
failed = true;
@@ -491,7 +490,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
491490
* errors in GetQueryResult through GetIdleSlot.)
492491
*/
493492
run_vacuum_command(free_slot->connection, sql.data,
494-
echo, dbname, tabname, progname, parallel);
493+
echo, tabname, progname, parallel);
495494

496495
if (cell)
497496
cell = cell->next;
@@ -504,7 +503,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
504503
for (j = 0; j < concurrentCons; j++)
505504
{
506505
/* wait for all connection to return the results */
507-
if (!GetQueryResult((slots + j)->connection, dbname, progname))
506+
if (!GetQueryResult((slots + j)->connection, progname))
508507
goto finish;
509508

510509
(slots + j)->isFree = true;
@@ -672,8 +671,7 @@ prepare_vacuum_command(PQExpBuffer sql, PGconn *conn, vacuumingOptions *vacopts,
672671
*/
673672
static void
674673
run_vacuum_command(PGconn *conn, const char *sql, bool echo,
675-
const char *dbname, const char *table,
676-
const char *progname, bool async)
674+
const char *table, const char *progname, bool async)
677675
{
678676
bool status;
679677

@@ -692,10 +690,10 @@ run_vacuum_command(PGconn *conn, const char *sql, bool echo,
692690
if (table)
693691
fprintf(stderr,
694692
_("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
695-
progname, table, dbname, PQerrorMessage(conn));
693+
progname, table, PQdb(conn), PQerrorMessage(conn));
696694
else
697695
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
698-
progname, dbname, PQerrorMessage(conn));
696+
progname, PQdb(conn), PQerrorMessage(conn));
699697

700698
if (!async)
701699
{
@@ -721,7 +719,7 @@ run_vacuum_command(PGconn *conn, const char *sql, bool echo,
721719
* If an error occurs, NULL is returned.
722720
*/
723721
static ParallelSlot *
724-
GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
722+
GetIdleSlot(ParallelSlot slots[], int numslots,
725723
const char *progname)
726724
{
727725
int i;
@@ -761,7 +759,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
761759
* We set the cancel-receiving connection to the one in the zeroth
762760
* slot above, so fetch the error from there.
763761
*/
764-
GetQueryResult(slots->connection, dbname, progname);
762+
GetQueryResult(slots->connection, progname);
765763
return NULL;
766764
}
767765
Assert(i != 0);
@@ -777,7 +775,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
777775

778776
(slots + i)->isFree = true;
779777

780-
if (!GetQueryResult((slots + i)->connection, dbname, progname))
778+
if (!GetQueryResult((slots + i)->connection, progname))
781779
return NULL;
782780

783781
if (firstFree < 0)
@@ -796,7 +794,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
796794
* reported and subsequently ignored.
797795
*/
798796
static bool
799-
GetQueryResult(PGconn *conn, const char *dbname, const char *progname)
797+
GetQueryResult(PGconn *conn, const char *progname)
800798
{
801799
PGresult *result;
802800

@@ -812,7 +810,7 @@ GetQueryResult(PGconn *conn, const char *dbname, const char *progname)
812810
char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE);
813811

814812
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
815-
progname, dbname, PQerrorMessage(conn));
813+
progname, PQdb(conn), PQerrorMessage(conn));
816814

817815
if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) != 0)
818816
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy