From a32bf47d9c2cad86c68e2bb58919dc73179f59c0 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Thu, 29 Jul 2021 15:59:28 -0700
Subject: [PATCH v5 06/12] Allow event trigger ownership by non-superusers

Non-superusers can already end up owning event triggers if superuser
is revoked from an event trigger owner, so quit the pretense and
simply allow the ownership transfer overtly by ALTER EVENT TRIGGER.

The prior situation did more to give a false sense that event
triggers would never be owned by non-superusers than it did to
actually prevent that scenario from arising.
---
 doc/src/sgml/ref/alter_event_trigger.sgml   |  4 +++-
 src/backend/commands/event_trigger.c        |  9 ++-------
 src/test/regress/expected/event_trigger.out | 17 +++++++++++++++--
 src/test/regress/sql/event_trigger.sql      | 21 +++++++++++++++++++++
 4 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/ref/alter_event_trigger.sgml b/doc/src/sgml/ref/alter_event_trigger.sgml
index ef5253bf37..54b7af5f99 100644
--- a/doc/src/sgml/ref/alter_event_trigger.sgml
+++ b/doc/src/sgml/ref/alter_event_trigger.sgml
@@ -37,7 +37,9 @@ ALTER EVENT TRIGGER <replaceable class="parameter">name</replaceable> RENAME TO
   </para>
 
   <para>
-   You must be superuser to alter an event trigger.
+   You must own the event trigger to use <command>ALTER EVENT TRIGGER</command>.
+   To alter the owner, you must also be a direct or indirect member of the
+   new owning role.
   </para>
  </refsect1>
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 71612d577e..93e211cecf 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -476,13 +476,8 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER,
 					   NameStr(form->evtname));
 
-	/* New owner must be a superuser */
-	if (!superuser_arg(newOwnerId))
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 errmsg("permission denied to change owner of event trigger \"%s\"",
-						NameStr(form->evtname)),
-				 errhint("The owner of an event trigger must be a superuser.")));
+	/* Must be able to assign ownership to the target role */
+	check_is_member_of_role(GetUserId(), newOwnerId);
 
 	form->evtowner = newOwnerId;
 	CatalogTupleUpdate(rel, &tup->t_self, tup);
diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out
index 44d545de25..d56c75de84 100644
--- a/src/test/regress/expected/event_trigger.out
+++ b/src/test/regress/expected/event_trigger.out
@@ -175,11 +175,24 @@ alter default privileges for role regress_evt_user
 NOTICE:  test_event_trigger: ddl_command_end ALTER DEFAULT PRIVILEGES
 -- alter owner to non-superuser should fail
 alter event trigger regress_event_trigger owner to regress_evt_user;
-ERROR:  permission denied to change owner of event trigger "regress_event_trigger"
-HINT:  The owner of an event trigger must be a superuser.
 -- alter owner to superuser should work
 alter role regress_evt_user superuser;
 alter event trigger regress_event_trigger owner to regress_evt_user;
+-- revoke superuser from new owner
+alter role regress_evt_user nosuperuser;
+create role regress_evt_user2;
+set session authorization regress_evt_user;
+-- fail - not a member of the target role
+alter event trigger regress_event_trigger owner to regress_evt_user2;
+ERROR:  must be member of role "regress_evt_user2"
+reset session authorization;
+grant regress_evt_user2 to regress_evt_user;
+set session authorization regress_evt_user;
+-- OK
+alter event trigger regress_event_trigger owner to regress_evt_user2;
+reset session authorization;
+alter event trigger regress_event_trigger owner to regress_evt_user;
+drop role regress_evt_user2;
 -- should fail, name collision
 alter event trigger regress_event_trigger rename to regress_event_trigger2;
 ERROR:  event trigger "regress_event_trigger2" already exists
diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql
index 1446cf8cc8..ef79b1059d 100644
--- a/src/test/regress/sql/event_trigger.sql
+++ b/src/test/regress/sql/event_trigger.sql
@@ -150,6 +150,27 @@ alter event trigger regress_event_trigger owner to regress_evt_user;
 alter role regress_evt_user superuser;
 alter event trigger regress_event_trigger owner to regress_evt_user;
 
+-- revoke superuser from new owner
+alter role regress_evt_user nosuperuser;
+
+create role regress_evt_user2;
+set session authorization regress_evt_user;
+
+-- fail - not a member of the target role
+alter event trigger regress_event_trigger owner to regress_evt_user2;
+
+reset session authorization;
+grant regress_evt_user2 to regress_evt_user;
+set session authorization regress_evt_user;
+
+-- OK
+alter event trigger regress_event_trigger owner to regress_evt_user2;
+
+reset session authorization;
+
+alter event trigger regress_event_trigger owner to regress_evt_user;
+drop role regress_evt_user2;
+
 -- should fail, name collision
 alter event trigger regress_event_trigger rename to regress_event_trigger2;
 
-- 
2.21.1 (Apple Git-122.3)

