diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/alter.c | 2 | ||||
-rw-r--r-- | src/backend/commands/dbcommands.c | 4 | ||||
-rw-r--r-- | src/backend/commands/foreigncmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/publicationcmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/schemacmds.c | 4 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/user.c | 44 | ||||
-rw-r--r-- | src/backend/commands/variable.c | 2 |
9 files changed, 51 insertions, 13 deletions
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index b2089d785b6..10b6fe19a2c 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -999,7 +999,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) objname); } /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), new_ownerId); + check_can_set_role(GetUserId(), new_ownerId); /* New owner must have CREATE privilege on namespace */ if (OidIsValid(namespaceId)) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index a67ea86619c..6eb87427181 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -941,7 +941,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to create database"))); - check_is_member_of_role(GetUserId(), datdba); + check_can_set_role(GetUserId(), datdba); /* * Lookup database (template) to be cloned, and obtain share lock on it. @@ -2495,7 +2495,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) dbname); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* * must have createdb rights diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 55b0be9e1d1..28b5c75f110 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -363,7 +363,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) NameStr(form->srvname)); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* New owner must have USAGE privilege on foreign-data wrapper */ aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE); diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 940655b9be0..20fa72c5c80 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -1911,7 +1911,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) NameStr(form->pubname)); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* New owner must have CREATE privilege on database */ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, newOwnerId, ACL_CREATE); diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index b03f07a2322..12cbfba7d06 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -97,7 +97,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString, aclcheck_error(aclresult, OBJECT_DATABASE, get_database_name(MyDatabaseId)); - check_is_member_of_role(saved_uid, owner_uid); + check_can_set_role(saved_uid, owner_uid); /* Additional check to protect reserved schema names */ if (!allowSystemTableMods && IsReservedName(schemaName)) @@ -370,7 +370,7 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) NameStr(nspForm->nspname)); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* * must have create-schema rights diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f0068078520..845208d662b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13833,7 +13833,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock RelationGetRelationName(target_rel)); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* New owner must have CREATE privilege on namespace */ aclresult = object_aclcheck(NamespaceRelationId, namespaceOid, newOwnerId, diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index ecc8b3f44c9..7770a86bee0 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -3745,7 +3745,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); + check_can_set_role(GetUserId(), newOwnerId); /* New owner must have CREATE privilege on namespace */ aclresult = object_aclcheck(NamespaceRelationId, typTup->typnamespace, diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 2369cc600c7..8b6543edee2 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -51,8 +51,8 @@ * RRG_REMOVE_ADMIN_OPTION indicates a grant that would need to have * admin_option set to false by the operation. * - * RRG_REMOVE_INHERIT_OPTION indicates a grant that would need to have - * inherit_option set to false by the operation. + * Similarly, RRG_REMOVE_INHERIT_OPTION and RRG_REMOVE_SET_OPTION indicate + * grants that would need to have the corresponding options set to false. * * RRG_DELETE_GRANT indicates a grant that would need to be removed entirely * by the operation. @@ -62,6 +62,7 @@ typedef enum RRG_NOOP, RRG_REMOVE_ADMIN_OPTION, RRG_REMOVE_INHERIT_OPTION, + RRG_REMOVE_SET_OPTION, RRG_DELETE_GRANT } RevokeRoleGrantAction; @@ -73,10 +74,12 @@ typedef struct unsigned specified; bool admin; bool inherit; + bool set; } GrantRoleOptions; #define GRANT_ROLE_SPECIFIED_ADMIN 0x0001 #define GRANT_ROLE_SPECIFIED_INHERIT 0x0002 +#define GRANT_ROLE_SPECIFIED_SET 0x0004 /* GUC parameter */ int Password_encryption = PASSWORD_TYPE_SCRAM_SHA_256; @@ -1389,6 +1392,12 @@ GrantRole(ParseState *pstate, GrantRoleStmt *stmt) if (parse_bool(optval, &popt.inherit)) continue; } + else if (strcmp(opt->defname, "set") == 0) + { + popt.specified |= GRANT_ROLE_SPECIFIED_SET; + if (parse_bool(optval, &popt.set)) + continue; + } else ereport(ERROR, errcode(ERRCODE_SYNTAX_ERROR), @@ -1776,6 +1785,16 @@ AddRoleMems(const char *rolename, Oid roleid, at_least_one_change = true; } + if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0 + && authmem_form->set_option != popt->set) + { + new_record[Anum_pg_auth_members_set_option - 1] = + BoolGetDatum(popt->set); + new_record_repl[Anum_pg_auth_members_set_option - 1] = + true; + at_least_one_change = true; + } + if (!at_least_one_change) { ereport(NOTICE, @@ -1798,9 +1817,15 @@ AddRoleMems(const char *rolename, Oid roleid, Oid objectId; Oid *newmembers = palloc(sizeof(Oid)); - /* Set admin option if user set it to true, otherwise not. */ + /* + * The values for these options can be taken directly from 'popt'. + * Either they were specified, or the defaults as set by + * InitGrantRoleOptions are correct. + */ new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(popt->admin); + new_record[Anum_pg_auth_members_set_option - 1] = + BoolGetDatum(popt->set); /* * If the user specified a value for the inherit option, use @@ -1989,6 +2014,13 @@ DelRoleMems(const char *rolename, Oid roleid, new_record_repl[Anum_pg_auth_members_inherit_option - 1] = true; } + else if (actions[i] == RRG_REMOVE_SET_OPTION) + { + new_record[Anum_pg_auth_members_set_option - 1] = + BoolGetDatum(false); + new_record_repl[Anum_pg_auth_members_set_option - 1] = + true; + } else elog(ERROR, "unknown role revoke action"); @@ -2182,6 +2214,11 @@ plan_single_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, */ actions[i] = RRG_REMOVE_INHERIT_OPTION; } + else if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0) + { + /* Here too, no need to recurse. */ + actions[i] = RRG_REMOVE_SET_OPTION; + } else { bool revoke_admin_option_only; @@ -2331,4 +2368,5 @@ InitGrantRoleOptions(GrantRoleOptions *popt) popt->specified = 0; popt->admin = false; popt->inherit = false; + popt->set = true; } diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 791bac6715c..00d8d54d820 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -939,7 +939,7 @@ check_role(char **newval, void **extra, GucSource source) * leader's state. */ if (!InitializingParallelWorker && - !is_member_of_role(GetSessionUserId(), roleid)) + !member_can_set_role(GetSessionUserId(), roleid)) { if (source == PGC_S_TEST) { |