public inbox for [email protected]  
help / color / mirror / Atom feed
From: Kirill Reshke <[email protected]>
To: [email protected]
Subject: Allow non-superuser to cancel superuser tasks.
Date: Mon, 26 Feb 2024 12:38:40 +0500
Message-ID: <CALdSSPhC4GGmbnugHfB9G0=fAxjCSug_-rmL9oUh0LTxsyBfsg@mail.gmail.com> (raw)

Hi hackers!

In our Cloud we have a patch, which allows non-superuser role ('mdb_admin')
to do some superuser things.
In particular, we have a patch that allows mdb admin to cancel the
autovacuum process and some other processes (processes with
application_name = 'MDB'), see the attachment.
This is needed to allow non-superuser roles to run pg_repack and to cancel
pg_repack.
We need to cancel running autovac to run pg_repack (because of locks), and
we need to cancel pg_repack sometimes also.

I want to reduce our internal patch size and transfer this logic to
extension or to core.
I have found similar threads [1] and [2], but, as far as I understand, they
do not solve this particular case.
I see 2 possible ways to implement this. The first one is to have hool in
pg_signal_backend, and define a hook in extension which can do the thing.
The second one is to have a predefined role. Something like a
`pg_signal_autovacuum` role which can signal running autovac to cancel. But
I don't see how we can handle specific `application_name` with this
solution.

[1]
https://www.postgresql.org/message-id/flat/F9408A5A-B20B-42D2-9E7F-49CD3D1547BC%40enterprisedb.com
[2]
https://www.postgresql.org/message-id/flat/20220722203735.GB3996698%40nathanxps13


Attachments:

  [application/octet-stream] v1-0001-cloud-mdb_admin-patch-part-to-illustrate.patch (1.9K, ../CALdSSPhC4GGmbnugHfB9G0=fAxjCSug_-rmL9oUh0LTxsyBfsg@mail.gmail.com/3-v1-0001-cloud-mdb_admin-patch-part-to-illustrate.patch)
  download | inline diff:
From 23b2805caf73f44167472b668702fb8746681ba3 Mon Sep 17 00:00:00 2001
From: Kirill Reshke <[email protected]>
Date: Mon, 26 Feb 2024 09:59:13 +0300
Subject: [PATCH v1] cloud mdb_admin patch part to illustrate.

---
 src/backend/storage/ipc/signalfuncs.c | 30 +++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index 81d1a59659..1885e31e7d 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -74,14 +74,40 @@ pg_signal_backend(int pid, int sig)
 		return SIGNAL_BACKEND_ERROR;
 	}
 
+	local_beentry = pgstat_get_local_beentry_by_backend_id(proc->backendId);
+	if (local_beentry != NULL)
+		beentry = &local_beentry->backendStatus;
 	/*
 	 * Only allow superusers to signal superuser-owned backends.  Any process
 	 * not advertising a role might have the importance of a superuser-owned
 	 * backend, so treat it that way.
 	 */
 	if ((!OidIsValid(proc->roleId) || superuser_arg(proc->roleId)) &&
-		!superuser())
-		return SIGNAL_BACKEND_NOSUPERUSER;
+		!superuser()) {
+		Oid role;
+		char * appname;
+
+		if (local_beentry == NULL) {
+			return SIGNAL_BACKEND_NOSUPERUSER;
+		}
+
+		role = get_role_oid("mdb_admin", true /*if nodoby created mdb_admin role in this database*/);
+		appname = local_beentry->backendStatus.st_appname;
+
+		// only allow mdb_admin to kill su queries
+		if (!is_member_of_role(GetUserId(), role)) {
+			return SIGNAL_BACKEND_NOSUPERUSER;
+		}
+
+		/* mdb admin allowed to kill proc with application name 'MDB' or autovacuum */
+		if (local_beentry->backendStatus.st_backendType == B_AUTOVAC_WORKER) {
+			// ok
+		} else if (appname != NULL && strcmp(appname, "MDB") == 0) {
+			// ok
+		} else {
+			return SIGNAL_BACKEND_NOSUPERUSER;
+		}
+	}
 
 	/* Users can signal backends they have role membership in. */
 	if (!has_privs_of_role(GetUserId(), proc->roleId) &&
-- 
2.43.1



view thread (2+ messages)

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: Allow non-superuser to cancel superuser tasks.
  In-Reply-To: <CALdSSPhC4GGmbnugHfB9G0=fAxjCSug_-rmL9oUh0LTxsyBfsg@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox