1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

Add grantable MAINTAIN privilege and pg_maintain role.

Allows VACUUM, ANALYZE, REINDEX, REFRESH MATERIALIZED VIEW, CLUSTER,
and LOCK TABLE.

Effectively reverts 4441fc704d. Instead of creating separate
privileges for VACUUM, ANALYZE, and other maintenance commands, group
them together under a single MAINTAIN privilege.

Author: Nathan Bossart
Discussion: https://postgr.es/m/20221212210136.GA449764@nathanxps13
Discussion: https://postgr.es/m/45224.1670476523@sss.pgh.pa.us
This commit is contained in:
Jeff Davis
2022-12-13 17:33:28 -08:00
parent c6f6646bb0
commit 60684dd834
36 changed files with 338 additions and 352 deletions

View File

@ -147,7 +147,8 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
tableOid = RangeVarGetRelidExtended(stmt->relation,
AccessExclusiveLock,
0,
RangeVarCallbackOwnsTable, NULL);
RangeVarCallbackMaintainsTable,
NULL);
rel = table_open(tableOid, NoLock);
/*
@ -364,8 +365,9 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
*/
if (recheck)
{
/* Check that the user still owns the relation */
if (!object_ownercheck(RelationRelationId, tableOid, save_userid))
/* Check that the user still has privileges for the relation */
if (!object_ownercheck(RelationRelationId, tableOid, save_userid) &&
pg_class_aclcheck(tableOid, save_userid, ACL_MAINTAIN) != ACLCHECK_OK)
{
relation_close(OldHeap, AccessExclusiveLock);
goto out;
@ -1612,7 +1614,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
/*
* Get a list of tables that the current user owns and
* Get a list of tables that the current user has privileges on and
* have indisclustered set. Return the list in a List * of RelToCluster
* (stored in the specified memory context), each one giving the tableOid
* and the indexOid on which the table is already clustered.
@ -1629,8 +1631,8 @@ get_tables_to_cluster(MemoryContext cluster_context)
List *rtcs = NIL;
/*
* Get all indexes that have indisclustered set and are owned by
* appropriate user.
* Get all indexes that have indisclustered set and that the current user
* has the appropriate privileges for.
*/
indRelation = table_open(IndexRelationId, AccessShareLock);
ScanKeyInit(&entry,
@ -1644,7 +1646,8 @@ get_tables_to_cluster(MemoryContext cluster_context)
index = (Form_pg_index) GETSTRUCT(indexTuple);
if (!object_ownercheck(RelationRelationId, index->indrelid, GetUserId()))
if (!object_ownercheck(RelationRelationId, index->indrelid, GetUserId()) &&
pg_class_aclcheck(index->indrelid, GetUserId(), ACL_MAINTAIN) != ACLCHECK_OK)
continue;
/* Use a permanent memory context for the result list */
@ -1694,6 +1697,7 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid)
/* Silently skip partitions which the user has no access to. */
if (!object_ownercheck(RelationRelationId, relid, GetUserId()) &&
pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) != ACLCHECK_OK &&
(!object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) ||
IsSharedRelation(relid)))
continue;