Skip to content

Commit fbcd24b

Browse files
committed
Have the client double-check that it is connected as a database superuser before plowing through initialization steps.
Addresses Issue #2.
1 parent 3b85662 commit fbcd24b

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

bin/pg_repack.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ typedef struct repack_index
8282
const char *create_index; /* CREATE INDEX */
8383
} repack_index;
8484

85+
static bool is_superuser(void);
8586
static void repack_all_databases(const char *order_by);
8687
static bool repack_one_database(const char *order_by, const char *table, char *errbuf, size_t errsize);
8788
static void repack_one_table(const repack_table *table, const char *order_by);
@@ -162,6 +163,31 @@ main(int argc, char *argv[])
162163
return 0;
163164
}
164165

166+
167+
/*
168+
* Test if the current user is a database superuser.
169+
* Borrowed from psql/common.c
170+
*
171+
* Note: this will correctly detect superuserness only with a protocol-3.0
172+
* or newer backend; otherwise it will always say "false".
173+
*/
174+
bool
175+
is_superuser(void)
176+
{
177+
const char *val;
178+
179+
if (!connection)
180+
return false;
181+
182+
val = PQparameterStatus(connection, "is_superuser");
183+
184+
if (val && strcmp(val, "on") == 0)
185+
return true;
186+
187+
return false;
188+
}
189+
190+
165191
/*
166192
* Call repack_one_database for each database.
167193
*/
@@ -173,6 +199,10 @@ repack_all_databases(const char *orderby)
173199

174200
dbname = "postgres";
175201
reconnect(ERROR);
202+
203+
if (!is_superuser())
204+
elog(ERROR, "You must be a superuser to use %s", PROGRAM_NAME);
205+
176206
result = execute("SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", 0, NULL);
177207
disconnect();
178208

@@ -230,7 +260,7 @@ static bool
230260
repack_one_database(const char *orderby, const char *table, char *errbuf, size_t errsize)
231261
{
232262
bool ret = false;
233-
PGresult *res;
263+
PGresult *res = NULL;
234264
int i;
235265
int num;
236266
StringInfoData sql;
@@ -239,6 +269,13 @@ repack_one_database(const char *orderby, const char *table, char *errbuf, size_t
239269

240270
reconnect(ERROR);
241271

272+
if (!is_superuser()) {
273+
if (errbuf)
274+
snprintf(errbuf, errsize, "You must be a superuser to use %s",
275+
PROGRAM_NAME);
276+
goto cleanup;
277+
}
278+
242279
/* Query the extension version. Exit if no match */
243280
res = execute_elevel("select repack.version(), repack.version_sql()",
244281
0, NULL, DEBUG2);
@@ -400,7 +437,8 @@ repack_one_database(const char *orderby, const char *table, char *errbuf, size_t
400437
ret = true;
401438

402439
cleanup:
403-
PQclear(res);
440+
if (res)
441+
PQclear(res);
404442
disconnect();
405443
termStringInfo(&sql);
406444
return ret;

0 commit comments

Comments
 (0)