aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/alter.c2
-rw-r--r--src/backend/commands/dbcommands.c4
-rw-r--r--src/backend/commands/foreigncmds.c2
-rw-r--r--src/backend/commands/publicationcmds.c2
-rw-r--r--src/backend/commands/schemacmds.c4
-rw-r--r--src/backend/commands/tablecmds.c2
-rw-r--r--src/backend/commands/typecmds.c2
-rw-r--r--src/backend/commands/user.c44
-rw-r--r--src/backend/commands/variable.c2
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)
{