From 07c396c208bd0f689810aca08995be17c826f3cb Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 26 Jul 2018 14:12:38 +0900
Subject: [PATCH 3/3] Restrict access to system-wide REINDEX for non-privileged
 users

A database owner running a system-wide REINDEX has the possibility to
also do the operation on critical system catalogs, which can cause a
PostgreSQL to go unresponsive or even block authentication.  This commit
makes sure that a user running a REINDEX SYSTEM or DATABASE only works
on the following relations:
- The user is a superuser
- The user is the table owner
- The user is the database owner, only if the relation worked on is not
shared.

Author: Michael Paquier
Discussion: https://postgr.es/m/152512087100.19803.12733865831237526317@wrigleys.postgresql.org
---
 src/backend/commands/indexcmds.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index b9dad9672e..1bfc34bc70 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2415,6 +2415,16 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
 			!IsSystemClass(relid, classtuple))
 			continue;
 
+		/*
+		 * We allow the user to reindex a table if he is superuser, the table
+		 * owner, or the database owner (but in the latter case, only if it's not
+		 * a shared relation).
+		 */
+		if (!(pg_class_ownercheck(relid, GetUserId()) ||
+			  (pg_database_ownercheck(MyDatabaseId, GetUserId()) &&
+			   !classtuple->relisshared)))
+			continue;
+
 		/* Save the list of relation OIDs in private context */
 		old = MemoryContextSwitchTo(private_context);
 
-- 
2.18.0

