@@ -82,6 +82,7 @@ typedef struct repack_index
82
82
const char * create_index ; /* CREATE INDEX */
83
83
} repack_index ;
84
84
85
+ static bool is_superuser (void );
85
86
static void repack_all_databases (const char * order_by );
86
87
static bool repack_one_database (const char * order_by , const char * table , char * errbuf , size_t errsize );
87
88
static void repack_one_table (const repack_table * table , const char * order_by );
@@ -162,6 +163,31 @@ main(int argc, char *argv[])
162
163
return 0 ;
163
164
}
164
165
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
+
165
191
/*
166
192
* Call repack_one_database for each database.
167
193
*/
@@ -173,6 +199,10 @@ repack_all_databases(const char *orderby)
173
199
174
200
dbname = "postgres" ;
175
201
reconnect (ERROR );
202
+
203
+ if (!is_superuser ())
204
+ elog (ERROR , "You must be a superuser to use %s" , PROGRAM_NAME );
205
+
176
206
result = execute ("SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;" , 0 , NULL );
177
207
disconnect ();
178
208
@@ -230,7 +260,7 @@ static bool
230
260
repack_one_database (const char * orderby , const char * table , char * errbuf , size_t errsize )
231
261
{
232
262
bool ret = false;
233
- PGresult * res ;
263
+ PGresult * res = NULL ;
234
264
int i ;
235
265
int num ;
236
266
StringInfoData sql ;
@@ -239,6 +269,13 @@ repack_one_database(const char *orderby, const char *table, char *errbuf, size_t
239
269
240
270
reconnect (ERROR );
241
271
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
+
242
279
/* Query the extension version. Exit if no match */
243
280
res = execute_elevel ("select repack.version(), repack.version_sql()" ,
244
281
0 , NULL , DEBUG2 );
@@ -400,7 +437,8 @@ repack_one_database(const char *orderby, const char *table, char *errbuf, size_t
400
437
ret = true;
401
438
402
439
cleanup :
403
- PQclear (res );
440
+ if (res )
441
+ PQclear (res );
404
442
disconnect ();
405
443
termStringInfo (& sql );
406
444
return ret ;
0 commit comments