From a296de742064c6e41f27ee995f932f3259f82312 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Mon, 21 Jun 2021 09:53:54 +0000 Subject: [PATCH] Add special case - mdb_admin group (cherry picked from commit 3ac99962ad23ec95bb9ef8967a4226e35cf97cc7) --- src/backend/commands/resgroupcmds.c | 36 +++++++++++++----- src/backend/utils/resgroup/resgroup_helper.c | 7 +++- src/test/regress/expected/resource_group.out | 40 +++++++++++++++++--- src/test/regress/sql/resource_group.sql | 24 ++++++++++++ 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/backend/commands/resgroupcmds.c b/src/backend/commands/resgroupcmds.c index 384675edb7f..320a389621f 100644 --- a/src/backend/commands/resgroupcmds.c +++ b/src/backend/commands/resgroupcmds.c @@ -102,12 +102,14 @@ CreateResourceGroup(CreateResourceGroupStmt *stmt) ResGroupCaps caps; int nResGroups; MemoryContext oldContext; + Oid role; - /* Permission check - only superuser can create groups. */ - if (!superuser()) + /* Permission check - only superuser or mdb_admin can create groups. */ + role = get_role_oid("mdb_admin", true); + if (!is_member_of_role(GetUserId(), role)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to create resource groups"))); + errmsg("must be mdb_admin to create resource groups"))); /* * Check for an illegal name ('none' is used to signify no group in ALTER ROLE). @@ -268,12 +270,20 @@ DropResourceGroup(DropResourceGroupStmt *stmt) SysScanDesc sscan; Oid groupid; ResourceGroupCallbackContext *callbackCtx; + Oid role; - /* Permission check - only superuser can drop resource groups. */ - if (!superuser()) + /* Permission check - only superuser or mdb_admin can drop resource groups. */ + role = get_role_oid("mdb_admin", true); + if (!is_member_of_role(GetUserId(), role)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to drop resource groups"))); + errmsg("must be mdb_admin to drop resource groups"))); + + /* Permission check - only superuser can drop resource group admin_group. */ + if (!superuser() && (strcmp(stmt->name, "admin_group") == 0)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to drop resource group admin_group"))); /* * Check the pg_resgroup relation to be certain the resource group already @@ -374,12 +384,20 @@ AlterResourceGroup(AlterResourceGroupStmt *stmt) char *io_limit = NULL; ResourceGroupCallbackContext *callbackCtx; MemoryContext oldContext; + Oid role; + + /* Permission check - only mdb_admin can alter resource groups. */ + role = get_role_oid("mdb_admin", true); + if (!is_member_of_role(GetUserId(), role)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be mdb_admin to alter resource groups"))); - /* Permission check - only superuser can alter resource groups. */ - if (!superuser()) + /* Permission check - only superuser can alter admin_group. */ + if (!superuser() && (strcmp(stmt->name, "admin_group") == 0)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter resource groups"))); + errmsg("must be superuser to alter resource group admin_group"))); /* Currently we only support to ALTER one limit at one time */ Assert(list_length(stmt->options) == 1); diff --git a/src/backend/utils/resgroup/resgroup_helper.c b/src/backend/utils/resgroup/resgroup_helper.c index 00aaded168d..4df203e3101 100644 --- a/src/backend/utils/resgroup/resgroup_helper.c +++ b/src/backend/utils/resgroup/resgroup_helper.c @@ -21,6 +21,7 @@ #include "cdb/cdbvars.h" #include "commands/resgroupcmds.h" #include "storage/procarray.h" +#include "utils/acl.h" #include "utils/builtins.h" #include "utils/datetime.h" #include "utils/resgroup.h" @@ -458,16 +459,18 @@ pg_resgroup_move_query(PG_FUNCTION_ARGS) int sessionId; Oid groupId; const char *groupName; + Oid role; if (!IsResGroupEnabled()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("resource group is not enabled")))); - if (!superuser()) + role = get_role_oid("mdb_admin", true); + if (!is_member_of_role(GetUserId(), role)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be superuser to move query")))); + (errmsg("must be mdb_admin to move query")))); if (Gp_role == GP_ROLE_DISPATCH) { diff --git a/src/test/regress/expected/resource_group.out b/src/test/regress/expected/resource_group.out index 0bcf2b14474..00588977f33 100644 --- a/src/test/regress/expected/resource_group.out +++ b/src/test/regress/expected/resource_group.out @@ -9,17 +9,11 @@ -- drop them. -- start_ignore DROP ROLE IF EXISTS role_dump_test1; -NOTICE: role "role_dump_test1" does not exist, skipping DROP ROLE IF EXISTS role_dump_test2; -NOTICE: role "role_dump_test2" does not exist, skipping DROP ROLE IF EXISTS role_dump_test3; -NOTICE: role "role_dump_test3" does not exist, skipping DROP RESOURCE GROUP rg_dump_test1; -ERROR: resource group "rg_dump_test1" does not exist DROP RESOURCE GROUP rg_dump_test2; -ERROR: resource group "rg_dump_test2" does not exist DROP RESOURCE GROUP rg_dump_test3; -ERROR: resource group "rg_dump_test3" does not exist -- end_ignore CREATE RESOURCE GROUP rg_dump_test1 WITH (concurrency=2, cpu_max_percent=5); WARNING: resource group is disabled @@ -42,3 +36,37 @@ CREATE ROLE role_dump_test3 RESOURCE GROUP rg_dump_test3; NOTICE: resource queue required -- using default resource queue "pg_default" WARNING: resource group is disabled HINT: To enable set gp_resource_manager=group +CREATE ROLE mdb_admin RESOURCE GROUP rg_dump_test1; +NOTICE: resource queue required -- using default resource queue "pg_default" +WARNING: resource group is disabled +HINT: To enable set gp_resource_manager=group +CREATE ROLE not_mdb_admin RESOURCE GROUP rg_dump_test1; +NOTICE: resource queue required -- using default resource queue "pg_default" +WARNING: resource group is disabled +HINT: To enable set gp_resource_manager=group +SET ROLE mdb_admin; +CREATE RESOURCE GROUP mdb_admin_test1 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +WARNING: resource group is disabled +HINT: To enable set gp_resource_manager=group +CREATE RESOURCE GROUP mdb_admin_test2 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +WARNING: resource group is disabled +HINT: To enable set gp_resource_manager=group +ALTER RESOURCE GROUP mdb_admin_test1 SET cpu_max_percent 2; +DROP RESOURCE GROUP mdb_admin_test1; +ALTER RESOURCE GROUP admin_group SET cpu_max_percent 2; +ERROR: must be superuser to alter resource group admin_group +DROP RESOURCE GROUP admin_group; +ERROR: must be superuser to drop resource group admin_group +SET ROLE not_mdb_admin; +CREATE RESOURCE GROUP mdb_admin_test1 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +ERROR: must be mdb_admin to create resource groups +ALTER RESOURCE GROUP mdb_admin_test2 SET cpu_max_percent 2; +ERROR: must be mdb_admin to alter resource groups +DROP RESOURCE GROUP mdb_admin_test2; +ERROR: must be mdb_admin to drop resource groups +DROP RESOURCE GROUP admin_group; +ERROR: must be mdb_admin to drop resource groups +RESET ROLE; +DROP RESOURCE GROUP mdb_admin_test2; +DROP ROLE mdb_admin; +DROP ROLE not_mdb_admin; diff --git a/src/test/regress/sql/resource_group.sql b/src/test/regress/sql/resource_group.sql index 1411eb0d61f..bfa3531ff88 100644 --- a/src/test/regress/sql/resource_group.sql +++ b/src/test/regress/sql/resource_group.sql @@ -25,3 +25,27 @@ CREATE RESOURCE GROUP rg_dump_test3 WITH (concurrency=2, cpu_max_percent=5); CREATE ROLE role_dump_test1 RESOURCE GROUP rg_dump_test1; CREATE ROLE role_dump_test2 RESOURCE GROUP rg_dump_test2; CREATE ROLE role_dump_test3 RESOURCE GROUP rg_dump_test3; + +CREATE ROLE mdb_admin RESOURCE GROUP rg_dump_test1; +CREATE ROLE not_mdb_admin RESOURCE GROUP rg_dump_test1; + +SET ROLE mdb_admin; + +CREATE RESOURCE GROUP mdb_admin_test1 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +CREATE RESOURCE GROUP mdb_admin_test2 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +ALTER RESOURCE GROUP mdb_admin_test1 SET cpu_max_percent 2; +DROP RESOURCE GROUP mdb_admin_test1; +ALTER RESOURCE GROUP admin_group SET cpu_max_percent 2; +DROP RESOURCE GROUP admin_group; + +SET ROLE not_mdb_admin; + +CREATE RESOURCE GROUP mdb_admin_test1 WITH (concurrency=2, cpu_max_percent=5, memory_quota=5); +ALTER RESOURCE GROUP mdb_admin_test2 SET cpu_max_percent 2; +DROP RESOURCE GROUP mdb_admin_test2; +DROP RESOURCE GROUP admin_group; + +RESET ROLE; +DROP RESOURCE GROUP mdb_admin_test2; +DROP ROLE mdb_admin; +DROP ROLE not_mdb_admin;