Skip to content

Commit c400717

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 9d924e9 commit c400717

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
@@ -264,7 +264,7 @@ main(int argc, char *argv[])
264264
* specified
265265
*/
266266
if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL)
267-
reindex_one_database(dbname, dbname, "DATABASE", host, port,
267+
reindex_one_database(NULL, dbname, "DATABASE", host, port,
268268
username, prompt_password, progname, echo, verbose);
269269
}
270270

@@ -281,6 +281,9 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
281281

282282
PGconn *conn;
283283

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

286289
appendPQExpBufferStr(&sql, "REINDEX");
@@ -295,26 +298,23 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
295298
else if (strcmp(type, "SCHEMA") == 0)
296299
appendPQExpBuffer(&sql, " SCHEMA %s", name);
297300
else if (strcmp(type, "DATABASE") == 0)
298-
appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
301+
appendPQExpBuffer(&sql, " DATABASE %s", fmtId(PQdb(conn)));
299302
appendPQExpBufferChar(&sql, ';');
300303

301-
conn = connectDatabase(dbname, host, port, username, prompt_password,
302-
progname, false, false);
303-
304304
if (!executeMaintenanceCommand(conn, sql.data, echo))
305305
{
306306
if (strcmp(type, "TABLE") == 0)
307307
fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
308-
progname, name, dbname, PQerrorMessage(conn));
308+
progname, name, PQdb(conn), PQerrorMessage(conn));
309309
if (strcmp(type, "INDEX") == 0)
310310
fprintf(stderr, _("%s: reindexing of index \"%s\" in database \"%s\" failed: %s"),
311-
progname, name, dbname, PQerrorMessage(conn));
311+
progname, name, PQdb(conn), PQerrorMessage(conn));
312312
if (strcmp(type, "SCHEMA") == 0)
313313
fprintf(stderr, _("%s: reindexing of schema \"%s\" in database \"%s\" failed: %s"),
314-
progname, name, dbname, PQerrorMessage(conn));
314+
progname, name, PQdb(conn), PQerrorMessage(conn));
315315
else
316316
fprintf(stderr, _("%s: reindexing of database \"%s\" failed: %s"),
317-
progname, dbname, PQerrorMessage(conn));
317+
progname, PQdb(conn), PQerrorMessage(conn));
318318
PQfinish(conn);
319319
exit(1);
320320
}
@@ -360,9 +360,11 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
360360
const char *username, enum trivalue prompt_password,
361361
const char *progname, bool echo, bool verbose)
362362
{
363+
PGconn *conn;
363364
PQExpBufferData sql;
364365

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

367369
initPQExpBuffer(&sql);
368370

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

374-
appendPQExpBuffer(&sql, " SYSTEM %s;", dbname);
376+
appendPQExpBuffer(&sql, " SYSTEM %s;", PQdb(conn));
375377

376-
conn = connectDatabase(dbname, host, port, username, prompt_password,
377-
progname, false, false);
378378
if (!executeMaintenanceCommand(conn, sql.data, echo))
379379
{
380380
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
@@ -58,14 +58,12 @@ static void prepare_vacuum_command(PQExpBuffer sql, PGconn *conn,
5858
vacuumingOptions *vacopts, const char *table);
5959

6060
static void run_vacuum_command(PGconn *conn, const char *sql, bool echo,
61-
const char *dbname, const char *table,
62-
const char *progname, bool async);
61+
const char *table, const char *progname, bool async);
6362

6463
static ParallelSlot *GetIdleSlot(ParallelSlot slots[], int numslots,
65-
const char *dbname, const char *progname);
64+
const char *progname);
6665

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

7068
static void DisconnectDatabase(ParallelSlot *slot);
7169

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

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

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

374373
/*
@@ -474,7 +473,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
474473
* Get a free slot, waiting until one becomes free if none
475474
* currently is.
476475
*/
477-
free_slot = GetIdleSlot(slots, concurrentCons, dbname, progname);
476+
free_slot = GetIdleSlot(slots, concurrentCons, progname);
478477
if (!free_slot)
479478
{
480479
failed = true;
@@ -492,7 +491,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
492491
* errors in GetQueryResult through GetIdleSlot.)
493492
*/
494493
run_vacuum_command(free_slot->connection, sql.data,
495-
echo, dbname, tabname, progname, parallel);
494+
echo, tabname, progname, parallel);
496495

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

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

@@ -693,10 +691,10 @@ run_vacuum_command(PGconn *conn, const char *sql, bool echo,
693691
if (table)
694692
fprintf(stderr,
695693
_("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
696-
progname, table, dbname, PQerrorMessage(conn));
694+
progname, table, PQdb(conn), PQerrorMessage(conn));
697695
else
698696
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
699-
progname, dbname, PQerrorMessage(conn));
697+
progname, PQdb(conn), PQerrorMessage(conn));
700698

701699
if (!async)
702700
{
@@ -722,7 +720,7 @@ run_vacuum_command(PGconn *conn, const char *sql, bool echo,
722720
* If an error occurs, NULL is returned.
723721
*/
724722
static ParallelSlot *
725-
GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
723+
GetIdleSlot(ParallelSlot slots[], int numslots,
726724
const char *progname)
727725
{
728726
int i;
@@ -762,7 +760,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
762760
* We set the cancel-receiving connection to the one in the zeroth
763761
* slot above, so fetch the error from there.
764762
*/
765-
GetQueryResult(slots->connection, dbname, progname);
763+
GetQueryResult(slots->connection, progname);
766764
return NULL;
767765
}
768766
Assert(i != 0);
@@ -778,7 +776,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
778776

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

781-
if (!GetQueryResult((slots + i)->connection, dbname, progname))
779+
if (!GetQueryResult((slots + i)->connection, progname))
782780
return NULL;
783781

784782
if (firstFree < 0)
@@ -797,7 +795,7 @@ GetIdleSlot(ParallelSlot slots[], int numslots, const char *dbname,
797795
* reported and subsequently ignored.
798796
*/
799797
static bool
800-
GetQueryResult(PGconn *conn, const char *dbname, const char *progname)
798+
GetQueryResult(PGconn *conn, const char *progname)
801799
{
802800
PGresult *result;
803801

@@ -813,7 +811,7 @@ GetQueryResult(PGconn *conn, const char *dbname, const char *progname)
813811
char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE);
814812

815813
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
816-
progname, dbname, PQerrorMessage(conn));
814+
progname, PQdb(conn), PQerrorMessage(conn));
817815

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

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