Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rOIuC-0035Os-Tg for pgsql-hackers@arkaria.postgresql.org; Fri, 12 Jan 2024 14:53:09 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rOIuC-002Xue-1P for pgsql-hackers@arkaria.postgresql.org; Fri, 12 Jan 2024 14:53:08 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rOIuB-002XuV-J5 for pgsql-hackers@lists.postgresql.org; Fri, 12 Jan 2024 14:53:07 +0000 Received: from mail-ed1-x52a.google.com ([2a00:1450:4864:20::52a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rOIu8-001Bzl-IA for pgsql-hackers@lists.postgresql.org; Fri, 12 Jan 2024 14:53:06 +0000 Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-5534dcfdd61so11558240a12.0 for ; Fri, 12 Jan 2024 06:53:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705071183; x=1705675983; darn=lists.postgresql.org; h=user-agent:content-disposition:mime-version:subject:to:from:date :sender:message-id:from:to:cc:subject:date:message-id:reply-to; bh=997Wr9cgNqGkMP9RQPOXTpJEmTh1bB7+4YYmsWV4LM4=; b=JnKpEe9tBawXo0ZpWnSwMM2Jitmj96+NnsY4GxU3sJ4i1wnAQzMvAckNG1uaeMJPQ9 WDExwCw/BbyfQCcnTuG29rpWzPGmou7l0S8ziUvGeaolZqhwE3BA57a4vsvROaARIY36 iknHI3ZlyOwiuHsaPnVKOP/JNJYOU6bpxGd3oh2VbvO+q8P7zAi8WX0gve/WLNJ9V5Iz GdxAULVhu6fndNRFBOYVsLjTs7msRxWJto/hIEiXXVgMucI3eJhBNyxgGyAh6duVyWDt tFRwrgAss5FyBNCzT1w58xbVS9U+IA5RKWNzgb/Jk7Kt3T4pGc9z33EbNe3/B+qIno5I Qpqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705071183; x=1705675983; h=user-agent:content-disposition:mime-version:subject:to:from:date :sender:message-id:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=997Wr9cgNqGkMP9RQPOXTpJEmTh1bB7+4YYmsWV4LM4=; b=YwKK5Av7NQfsLyGjpdY6FFThqLSnxrPhlAIxZASmztKLEBj/E+T+qVHYgg0t3Myu1k tgiOQpJUI3HHJVLSb0uW2zY+gkAeXjtoXxIXs9mWy/cEyRjD4nf8QACETjarWB3qAbi6 gbWGcUvyUNYb7qhoaSa/eId7Vd5hbquPJCL6g9AkYGXbl66jAQwjb5lrarl65xtjrO2R XFTP2jfGA4u01HhLjaTQjAg13c+neFTB+hvNKxDLYqejTKSE+GsP94pEAjGXbvfSS6Kp YEjXD94PFBm0wYtwMiwN0jokMdPlQW3mORnAnbFHYNQmRwke28OhVs2oS7siDq5m/yt/ ejLA== X-Gm-Message-State: AOJu0YzbnP1J3KvvbXtga/0+ciQ7AI7H/ke0CtLudpn0Ef0lqNGQgLBd vTX6Z3//d1qqYhnVw3bmnVvs8Gf5GDm22w== X-Google-Smtp-Source: AGHT+IHz0KnR/yXt9quLKeGxS941IqBDOO1qhYjtQvVVMA1aC7eh9vibntcCvtb2wwqqOjQvBxiDOQ== X-Received: by 2002:a50:ccd0:0:b0:557:1ab5:da56 with SMTP id b16-20020a50ccd0000000b005571ab5da56mr1335045edj.42.1705071182977; Fri, 12 Jan 2024 06:53:02 -0800 (PST) Received: from lightning.caipicrew.dd-dns.de ([2001:a61:10cd:8701:ed11:b7eb:8de7:fbd6]) by smtp.gmail.com with ESMTPSA id et6-20020a056402378600b0055410f0d709sm1837380edb.19.2024.01.12.06.53.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jan 2024 06:53:02 -0800 (PST) Message-ID: <65a1524e.050a0220.49266.7670@mx.google.com> X-Google-Original-Message-ID: <20240112145301.GA17618@caipicrew.dd-dns.de;lightning.caipicrew.dd-dns.de> Sender: Michael Banck Received: from mbanck by lightning.caipicrew.dd-dns.de with local (Exim 4.92) (envelope-from ) id 1rOIu6-0004rB-0J for pgsql-hackers@lists.postgresql.org; Fri, 12 Jan 2024 15:53:02 +0100 Date: Fri, 12 Jan 2024 15:53:01 +0100 From: Michael Banck To: PostgreSQL Hackers Subject: [PATCH] New predefined role pg_manage_extensions MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="UlVJffcvxoiEqYs2" Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, I propose to add a new predefined role to Postgres, pg_manage_extensions. The idea is that it allows Superusers to delegate the rights to create, update or delete extensions to other roles, even if those extensions are not trusted or those users are not the database owner. I have attached a WIP patch for this. Thoughts? Michael --UlVJffcvxoiEqYs2 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-Add-new-pg_manage_extensions-predefined-role.patch" From 59497e825184f0de30a18573ffd7d331be3b233d Mon Sep 17 00:00:00 2001 From: Michael Banck Date: Fri, 12 Jan 2024 13:56:59 +0100 Subject: [PATCH] Add new pg_manage_extensions predefined role. This allows any role that is granted this new predefined role to CREATE, UPDATE or DROP extensions, no matter whether they are trusted or not. --- doc/src/sgml/user-manag.sgml | 5 +++++ src/backend/commands/extension.c | 11 ++++++----- src/include/catalog/pg_authid.dat | 5 +++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 92a299d2d3..ebb82801ec 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -693,6 +693,11 @@ DROP ROLE doomed_role; database to issue CREATE SUBSCRIPTION. + + pg_manage_extensions + Allow creating, removing or updating extensions, even if the + extensions are untrusted or the user is not the database owner. + diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 226f85d0e3..71481d9a73 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -882,13 +882,14 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, ListCell *lc2; /* - * Enforce superuser-ness if appropriate. We postpone these checks until - * here so that the control flags are correctly associated with the right + * Enforce superuser-ness/membership of the pg_manage_extensions + * predefined role if appropriate. We postpone these checks until here + * so that the control flags are correctly associated with the right * script(s) if they happen to be set in secondary control files. */ if (control->superuser && !superuser()) { - if (extension_is_trusted(control)) + if (extension_is_trusted(control) || has_privs_of_role(GetUserId(), ROLE_PG_MANAGE_EXTENSIONS)) switch_to_superuser = true; else if (from_version == NULL) ereport(ERROR, @@ -897,7 +898,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, control->name), control->trusted ? errhint("Must have CREATE privilege on current database to create this extension.") - : errhint("Must be superuser to create this extension."))); + : errhint("Only roles with privileges of the \"%s\" role are allowed to create this extension.", "pg_manage_extensions"))); else ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), @@ -905,7 +906,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, control->name), control->trusted ? errhint("Must have CREATE privilege on current database to update this extension.") - : errhint("Must be superuser to update this extension."))); + : errhint("Only roles with privileges of the \"%s\" role are allowed to update this extension.", "pg_manage_extensions"))); } filename = get_extension_script_filename(control, from_version, version); diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat index 82a2ec2862..ac70603d26 100644 --- a/src/include/catalog/pg_authid.dat +++ b/src/include/catalog/pg_authid.dat @@ -94,5 +94,10 @@ rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', rolpassword => '_null_', rolvaliduntil => '_null_' }, +{ oid => '8801', oid_symbol => 'ROLE_PG_MANAGE_EXTENSIONS', + rolname => 'pg_manage_extensions', rolsuper => 'f', rolinherit => 't', + rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', + rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', + rolpassword => '_null_', rolvaliduntil => '_null_' }, ] -- 2.39.2 --UlVJffcvxoiEqYs2--