From afbfc02983f86c4d71825efa6befd547fe81a926 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sun, 13 Nov 2022 08:11:17 +0100 Subject: [PATCH] Refactor ownercheck functions Instead of dozens of mostly-duplicate pg_foo_ownercheck() functions, write one common function object_ownercheck() that can handle almost all of them. We already have all the information we need, such as which system catalog corresponds to which catalog table and which column is the owner column. Reviewed-by: Corey Huinker Reviewed-by: Antonin Houska Discussion: https://www.postgresql.org/message-id/flat/95c30f96-4060-2f48-98b5-a4392d3b6066@enterprisedb.com --- contrib/pg_surgery/heap_surgery.c | 2 +- src/backend/access/brin/brin.c | 4 +- src/backend/access/gin/ginfast.c | 2 +- src/backend/catalog/aclchk.c | 663 +++--------------------- src/backend/catalog/namespace.c | 2 +- src/backend/catalog/objectaddress.c | 108 +--- src/backend/catalog/pg_operator.c | 6 +- src/backend/catalog/pg_proc.c | 2 +- src/backend/commands/cluster.c | 9 +- src/backend/commands/collationcmds.c | 2 +- src/backend/commands/dbcommands.c | 16 +- src/backend/commands/dropcmds.c | 3 +- src/backend/commands/event_trigger.c | 4 +- src/backend/commands/extension.c | 6 +- src/backend/commands/foreigncmds.c | 6 +- src/backend/commands/functioncmds.c | 12 +- src/backend/commands/indexcmds.c | 12 +- src/backend/commands/opclasscmds.c | 16 +- src/backend/commands/operatorcmds.c | 2 +- src/backend/commands/policy.c | 2 +- src/backend/commands/proclang.c | 2 +- src/backend/commands/publicationcmds.c | 6 +- src/backend/commands/schemacmds.c | 4 +- src/backend/commands/statscmds.c | 4 +- src/backend/commands/subscriptioncmds.c | 6 +- src/backend/commands/tablecmds.c | 22 +- src/backend/commands/tablespace.c | 6 +- src/backend/commands/trigger.c | 2 +- src/backend/commands/tsearchcmds.c | 4 +- src/backend/commands/typecmds.c | 28 +- src/backend/commands/user.c | 4 +- src/backend/commands/vacuum.c | 6 +- src/backend/libpq/be-fsstubs.c | 3 +- src/backend/rewrite/rewriteDefine.c | 6 +- src/backend/utils/adt/ri_triggers.c | 4 +- src/backend/utils/misc/rls.c | 2 +- src/include/utils/acl.h | 23 +- 37 files changed, 194 insertions(+), 817 deletions(-) diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index 8a2ad9773d..191ce72c23 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -118,7 +118,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) errmsg("only heap AM is supported"))); /* Must be owner of the table or superuser. */ - if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 20b7d65b94..7e386250ae 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1069,7 +1069,7 @@ brin_summarize_range(PG_FUNCTION_ARGS) RelationGetRelationName(indexRel)))); /* User must own the index (comparable to privileges needed for VACUUM) */ - if (heapRel != NULL && !pg_class_ownercheck(indexoid, save_userid)) + if (heapRel != NULL && !object_ownercheck(RelationRelationId, indexoid, save_userid)) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, RelationGetRelationName(indexRel)); @@ -1152,7 +1152,7 @@ brin_desummarize_range(PG_FUNCTION_ARGS) RelationGetRelationName(indexRel)))); /* User must own the index (comparable to privileges needed for VACUUM) */ - if (!pg_class_ownercheck(indexoid, GetUserId())) + if (!object_ownercheck(RelationRelationId, indexoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, RelationGetRelationName(indexRel)); diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index f750b5ed9e..0435598bd1 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -1054,7 +1054,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS) errmsg("cannot access temporary indexes of other sessions"))); /* User must own the index (comparable to privileges needed for VACUUM) */ - if (!pg_class_ownercheck(indexoid, GetUserId())) + if (!object_ownercheck(RelationRelationId, indexoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, RelationGetRelationName(indexRel)); diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 42360d37ca..7302f03508 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -32,6 +32,7 @@ #include "catalog/pg_am.h" #include "catalog/pg_authid.h" #include "catalog/pg_cast.h" +#include "catalog/pg_class.h" #include "catalog/pg_collation.h" #include "catalog/pg_conversion.h" #include "catalog/pg_database.h" @@ -5111,618 +5112,74 @@ pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode) } /* - * Ownership check for a relation (specified by OID). + * Generic ownership check for an object */ bool -pg_class_ownercheck(Oid class_oid, Oid roleid) +object_ownercheck(Oid classid, Oid objectid, Oid roleid) { - HeapTuple tuple; + int cacheid; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("relation with OID %u does not exist", class_oid))); - - ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a type (specified by OID). - */ -bool -pg_type_ownercheck(Oid type_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type with OID %u does not exist", type_oid))); - - ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for an operator (specified by OID). - */ -bool -pg_oper_ownercheck(Oid oper_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(oper_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("operator with OID %u does not exist", oper_oid))); - - ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a function (specified by OID). - */ -bool -pg_proc_ownercheck(Oid proc_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("function with OID %u does not exist", proc_oid))); - - ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a procedural language (specified by OID) - */ -bool -pg_language_ownercheck(Oid lan_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("language with OID %u does not exist", lan_oid))); - - ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a largeobject (specified by OID) - * - * This is only used for operations like ALTER LARGE OBJECT that are always - * relative to an up-to-date snapshot. - */ -bool -pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid) -{ - Relation pg_lo_meta; - ScanKeyData entry[1]; - SysScanDesc scan; - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - /* There's no syscache for pg_largeobject_metadata */ - pg_lo_meta = table_open(LargeObjectMetadataRelationId, - AccessShareLock); - - ScanKeyInit(&entry[0], - Anum_pg_largeobject_metadata_oid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(lobj_oid)); - - scan = systable_beginscan(pg_lo_meta, - LargeObjectMetadataOidIndexId, true, - NULL, 1, entry); - - tuple = systable_getnext(scan); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("large object %u does not exist", lobj_oid))); - - ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner; - - systable_endscan(scan); - table_close(pg_lo_meta, AccessShareLock); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a namespace (specified by OID). - */ -bool -pg_namespace_ownercheck(Oid nsp_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("schema with OID %u does not exist", nsp_oid))); - - ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a tablespace (specified by OID). - */ -bool -pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) -{ - HeapTuple spctuple; - Oid spcowner; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - /* Search syscache for pg_tablespace */ - spctuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid)); - if (!HeapTupleIsValid(spctuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("tablespace with OID %u does not exist", spc_oid))); - - spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner; - - ReleaseSysCache(spctuple); - - return has_privs_of_role(roleid, spcowner); -} - -/* - * Ownership check for an operator class (specified by OID). - */ -bool -pg_opclass_ownercheck(Oid opc_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opc_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("operator class with OID %u does not exist", - opc_oid))); - - ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for an operator family (specified by OID). - */ -bool -pg_opfamily_ownercheck(Oid opf_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opf_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("operator family with OID %u does not exist", - opf_oid))); - - ownerId = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a text search dictionary (specified by OID). - */ -bool -pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dict_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("text search dictionary with OID %u does not exist", - dict_oid))); - - ownerId = ((Form_pg_ts_dict) GETSTRUCT(tuple))->dictowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a text search configuration (specified by OID). - */ -bool -pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfg_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("text search configuration with OID %u does not exist", - cfg_oid))); - - ownerId = ((Form_pg_ts_config) GETSTRUCT(tuple))->cfgowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a foreign-data wrapper (specified by OID). - */ -bool -pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(srv_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("foreign-data wrapper with OID %u does not exist", - srv_oid))); - - ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a foreign server (specified by OID). - */ -bool -pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srv_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("foreign server with OID %u does not exist", - srv_oid))); - - ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for an event trigger (specified by OID). - */ -bool -pg_event_trigger_ownercheck(Oid et_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(et_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("event trigger with OID %u does not exist", - et_oid))); - - ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a database (specified by OID). - */ -bool -pg_database_ownercheck(Oid db_oid, Oid roleid) -{ - HeapTuple tuple; - Oid dba; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_DATABASE), - errmsg("database with OID %u does not exist", db_oid))); - - dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, dba); -} - -/* - * Ownership check for a collation (specified by OID). - */ -bool -pg_collation_ownercheck(Oid coll_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("collation with OID %u does not exist", coll_oid))); - - ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a conversion (specified by OID). - */ -bool -pg_conversion_ownercheck(Oid conv_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("conversion with OID %u does not exist", conv_oid))); - - ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for an extension (specified by OID). - */ -bool -pg_extension_ownercheck(Oid ext_oid, Oid roleid) -{ - Relation pg_extension; - ScanKeyData entry[1]; - SysScanDesc scan; - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - /* There's no syscache for pg_extension, so do it the hard way */ - pg_extension = table_open(ExtensionRelationId, AccessShareLock); - - ScanKeyInit(&entry[0], - Anum_pg_extension_oid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(ext_oid)); - - scan = systable_beginscan(pg_extension, - ExtensionOidIndexId, true, - NULL, 1, entry); - - tuple = systable_getnext(scan); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("extension with OID %u does not exist", ext_oid))); - - ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner; - - systable_endscan(scan); - table_close(pg_extension, AccessShareLock); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a publication (specified by OID). - */ -bool -pg_publication_ownercheck(Oid pub_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pub_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("publication with OID %u does not exist", pub_oid))); - - ownerId = ((Form_pg_publication) GETSTRUCT(tuple))->pubowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a subscription (specified by OID). - */ -bool -pg_subscription_ownercheck(Oid sub_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(sub_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("subscription with OID %u does not exist", sub_oid))); - - ownerId = ((Form_pg_subscription) GETSTRUCT(tuple))->subowner; - - ReleaseSysCache(tuple); - - return has_privs_of_role(roleid, ownerId); -} - -/* - * Ownership check for a statistics object (specified by OID). - */ -bool -pg_statistics_object_ownercheck(Oid stat_oid, Oid roleid) -{ - HeapTuple tuple; - Oid ownerId; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(roleid)) - return true; - - tuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stat_oid)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("statistics object with OID %u does not exist", - stat_oid))); - - ownerId = ((Form_pg_statistic_ext) GETSTRUCT(tuple))->stxowner; - - ReleaseSysCache(tuple); + cacheid = get_object_catcache_oid(classid); + if (cacheid != -1) + { + HeapTuple tuple; + bool isnull; + + tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid))); + + ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid, + tuple, + get_object_attnum_owner(classid), + &isnull)); + Assert(!isnull); + + ReleaseSysCache(tuple); + } + else + { + /* for catalogs without an appropriate syscache */ + + Relation rel; + ScanKeyData entry[1]; + SysScanDesc scan; + HeapTuple tuple; + bool isnull; + + rel = table_open(classid, AccessShareLock); + + ScanKeyInit(&entry[0], + get_object_attnum_oid(classid), + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objectid)); + + scan = systable_beginscan(rel, + get_object_oid_index(classid), true, + NULL, 1, entry); + + tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid))); + + ownerId = DatumGetObjectId(heap_getattr(tuple, + get_object_attnum_owner(classid), + RelationGetDescr(rel), + &isnull)); + Assert(!isnull); + + systable_endscan(scan); + table_close(rel, AccessShareLock); + } return has_privs_of_role(roleid, ownerId); } diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 539df1da94..1543f2abcd 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -612,7 +612,7 @@ RangeVarGetAndCheckCreationNamespace(RangeVar *relation, /* Lock relation, if required if and we have permission. */ if (lockmode != NoLock && OidIsValid(relid)) { - if (!pg_class_ownercheck(relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), relation->relname); if (relid != oldrelid) diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index c7de7232b8..9dad77c28a 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -2439,19 +2439,14 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, case OBJECT_TRIGGER: case OBJECT_POLICY: case OBJECT_TABCONSTRAINT: - if (!pg_class_ownercheck(RelationGetRelid(relation), roleid)) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, objtype, RelationGetRelationName(relation)); break; - case OBJECT_DATABASE: - if (!pg_database_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; case OBJECT_TYPE: case OBJECT_DOMAIN: case OBJECT_ATTRIBUTE: - if (!pg_type_ownercheck(address.objectId, roleid)) + if (!object_ownercheck(address.classId, address.objectId, roleid)) aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId); break; case OBJECT_DOMCONSTRAINT: @@ -2473,7 +2468,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, * Fallback to type ownership check in this case as this is * what domain constraints rely on. */ - if (!pg_type_ownercheck(contypid, roleid)) + if (!object_ownercheck(TypeRelationId, contypid, roleid)) aclcheck_error_type(ACLCHECK_NOT_OWNER, contypid); } break; @@ -2481,68 +2476,39 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, case OBJECT_FUNCTION: case OBJECT_PROCEDURE: case OBJECT_ROUTINE: - if (!pg_proc_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString((castNode(ObjectWithArgs, object))->objname)); - break; case OBJECT_OPERATOR: - if (!pg_oper_ownercheck(address.objectId, roleid)) + if (!object_ownercheck(address.classId, address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, objtype, NameListToString((castNode(ObjectWithArgs, object))->objname)); break; + case OBJECT_DATABASE: + case OBJECT_EVENT_TRIGGER: + case OBJECT_EXTENSION: + case OBJECT_FDW: + case OBJECT_FOREIGN_SERVER: + case OBJECT_LANGUAGE: + case OBJECT_PUBLICATION: case OBJECT_SCHEMA: - if (!pg_namespace_ownercheck(address.objectId, roleid)) + case OBJECT_SUBSCRIPTION: + case OBJECT_TABLESPACE: + if (!object_ownercheck(address.classId, address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, objtype, strVal(object)); break; case OBJECT_COLLATION: - if (!pg_collation_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; case OBJECT_CONVERSION: - if (!pg_conversion_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; - case OBJECT_EXTENSION: - if (!pg_extension_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_FDW: - if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_FOREIGN_SERVER: - if (!pg_foreign_server_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_EVENT_TRIGGER: - if (!pg_event_trigger_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_LANGUAGE: - if (!pg_language_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; case OBJECT_OPCLASS: - if (!pg_opclass_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; case OBJECT_OPFAMILY: - if (!pg_opfamily_ownercheck(address.objectId, roleid)) + case OBJECT_STATISTIC_EXT: + case OBJECT_TSDICTIONARY: + case OBJECT_TSCONFIGURATION: + if (!object_ownercheck(address.classId, address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, objtype, NameListToString(castNode(List, object))); break; case OBJECT_LARGEOBJECT: if (!lo_compat_privileges && - !pg_largeobject_ownercheck(address.objectId, roleid)) + !object_ownercheck(address.classId, address.objectId, roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of large object %u", @@ -2556,8 +2522,8 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Oid sourcetypeid = typenameTypeId(NULL, sourcetype); Oid targettypeid = typenameTypeId(NULL, targettype); - if (!pg_type_ownercheck(sourcetypeid, roleid) - && !pg_type_ownercheck(targettypeid, roleid)) + if (!object_ownercheck(TypeRelationId, sourcetypeid, roleid) + && !object_ownercheck(TypeRelationId, targettypeid, roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of type %s or type %s", @@ -2565,40 +2531,15 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, format_type_be(targettypeid)))); } break; - case OBJECT_PUBLICATION: - if (!pg_publication_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_SUBSCRIPTION: - if (!pg_subscription_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; case OBJECT_TRANSFORM: { TypeName *typename = linitial_node(TypeName, castNode(List, object)); Oid typeid = typenameTypeId(NULL, typename); - if (!pg_type_ownercheck(typeid, roleid)) + if (!object_ownercheck(TypeRelationId, typeid, roleid)) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid); } break; - case OBJECT_TABLESPACE: - if (!pg_tablespace_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - strVal(object)); - break; - case OBJECT_TSDICTIONARY: - if (!pg_ts_dict_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; - case OBJECT_TSCONFIGURATION: - if (!pg_ts_config_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; case OBJECT_ROLE: /* @@ -2630,11 +2571,6 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser"))); break; - case OBJECT_STATISTIC_EXT: - if (!pg_statistics_object_ownercheck(address.objectId, roleid)) - aclcheck_error(ACLCHECK_NOT_OWNER, objtype, - NameListToString(castNode(List, object))); - break; default: elog(ERROR, "unrecognized object type: %d", (int) objtype); diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 3947ad8980..e6e794b6ff 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -427,7 +427,7 @@ OperatorCreate(const char *operatorName, * such shell. */ if (OidIsValid(operatorObjectId) && - !pg_oper_ownercheck(operatorObjectId, GetUserId())) + !object_ownercheck(OperatorRelationId, operatorObjectId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, operatorName); @@ -447,7 +447,7 @@ OperatorCreate(const char *operatorName, /* Permission check: must own other operator */ if (OidIsValid(commutatorId) && - !pg_oper_ownercheck(commutatorId, GetUserId())) + !object_ownercheck(OperatorRelationId, commutatorId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, NameListToString(commutatorName)); @@ -472,7 +472,7 @@ OperatorCreate(const char *operatorName, /* Permission check: must own other operator */ if (OidIsValid(negatorId) && - !pg_oper_ownercheck(negatorId, GetUserId())) + !object_ownercheck(OperatorRelationId, negatorId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, NameListToString(negatorName)); } diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index e03b98bcd2..69f43aa0ec 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -375,7 +375,7 @@ ProcedureCreate(const char *procedureName, (errcode(ERRCODE_DUPLICATE_FUNCTION), errmsg("function \"%s\" already exists with same argument types", procedureName))); - if (!pg_proc_ownercheck(oldproc->oid, proowner)) + if (!object_ownercheck(ProcedureRelationId, oldproc->oid, proowner)) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, procedureName); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 1976a373ef..3b78a2f100 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -34,6 +34,7 @@ #include "catalog/objectaccess.h" #include "catalog/partition.h" #include "catalog/pg_am.h" +#include "catalog/pg_database.h" #include "catalog/pg_inherits.h" #include "catalog/toasting.h" #include "commands/cluster.h" @@ -364,7 +365,7 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params) if (recheck) { /* Check that the user still owns the relation */ - if (!pg_class_ownercheck(tableOid, save_userid)) + if (!object_ownercheck(RelationRelationId, tableOid, save_userid)) { relation_close(OldHeap, AccessExclusiveLock); goto out; @@ -1641,7 +1642,7 @@ get_tables_to_cluster(MemoryContext cluster_context) index = (Form_pg_index) GETSTRUCT(indexTuple); - if (!pg_class_ownercheck(index->indrelid, GetUserId())) + if (!object_ownercheck(RelationRelationId, index->indrelid, GetUserId())) continue; /* Use a permanent memory context for the result list */ @@ -1690,8 +1691,8 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid) continue; /* Silently skip partitions which the user has no access to. */ - if (!pg_class_ownercheck(relid, GetUserId()) && - (!pg_database_ownercheck(MyDatabaseId, GetUserId()) || + if (!object_ownercheck(RelationRelationId, relid, GetUserId()) && + (!object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) || IsSharedRelation(relid))) continue; diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 86fbc7fa01..1753d67b61 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -371,7 +371,7 @@ AlterCollation(AlterCollationStmt *stmt) (errmsg("cannot refresh version of default collation"), errhint("Use ALTER DATABASE ... REFRESH COLLATION VERSION instead."))); - if (!pg_collation_ownercheck(collOid, GetUserId())) + if (!object_ownercheck(CollationRelationId, collOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_COLLATION, NameListToString(stmt->collname)); diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 8abc2c3e0b..0d6a122863 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -972,7 +972,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) */ if (!src_istemplate) { - if (!pg_database_ownercheck(src_dboid, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, src_dboid, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to copy database \"%s\"", @@ -1549,7 +1549,7 @@ dropdb(const char *dbname, bool missing_ok, bool force) /* * Permission checks */ - if (!pg_database_ownercheck(db_id, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, dbname); @@ -1733,7 +1733,7 @@ RenameDatabase(const char *oldname, const char *newname) errmsg("database \"%s\" does not exist", oldname))); /* must be owner */ - if (!pg_database_ownercheck(db_id, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, oldname); @@ -1854,7 +1854,7 @@ movedb(const char *dbname, const char *tblspcname) /* * Permission checks */ - if (!pg_database_ownercheck(db_id, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, dbname); @@ -2281,7 +2281,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) datform = (Form_pg_database) GETSTRUCT(tuple); dboid = datform->oid; - if (!pg_database_ownercheck(dboid, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, dboid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, stmt->dbname); @@ -2364,7 +2364,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt) datForm = (Form_pg_database) GETSTRUCT(tuple); db_id = datForm->oid; - if (!pg_database_ownercheck(db_id, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, stmt->dbname); @@ -2427,7 +2427,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) */ shdepLockAndCheckObject(DatabaseRelationId, datid); - if (!pg_database_ownercheck(datid, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, datid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, stmt->dbname); @@ -2490,7 +2490,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) HeapTuple newtuple; /* Otherwise, must be owner of the existing object */ - if (!pg_database_ownercheck(db_id, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, dbname); diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 26157eb4e3..389fc6a102 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -21,6 +21,7 @@ #include "catalog/namespace.h" #include "catalog/objectaddress.h" #include "catalog/pg_class.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "commands/defrem.h" #include "miscadmin.h" @@ -105,7 +106,7 @@ RemoveObjects(DropStmt *stmt) /* Check permissions. */ namespaceId = get_object_namespace(&address); if (!OidIsValid(namespaceId) || - !pg_namespace_ownercheck(namespaceId, GetUserId())) + !object_ownercheck(NamespaceRelationId, namespaceId, GetUserId())) check_object_ownership(GetUserId(), stmt->removeType, address, object, relation); diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 8d36b66488..a3bdc5db07 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -379,7 +379,7 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) evtForm = (Form_pg_event_trigger) GETSTRUCT(tup); trigoid = evtForm->oid; - if (!pg_event_trigger_ownercheck(trigoid, GetUserId())) + if (!object_ownercheck(EventTriggerRelationId, trigoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER, stmt->trigname); @@ -471,7 +471,7 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) if (form->evtowner == newOwnerId) return; - if (!pg_event_trigger_ownercheck(form->oid, GetUserId())) + if (!object_ownercheck(EventTriggerRelationId, form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER, NameStr(form->evtname)); diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 1a62e5dac5..722e94bbce 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2727,7 +2727,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o * Permission check: must own extension. Note that we don't bother to * check ownership of the individual member objects ... */ - if (!pg_extension_ownercheck(extensionOid, GetUserId())) + if (!object_ownercheck(ExtensionRelationId, extensionOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EXTENSION, extensionName); @@ -2947,7 +2947,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt) table_close(extRel, AccessShareLock); /* Permission check: must own extension */ - if (!pg_extension_ownercheck(extensionOid, GetUserId())) + if (!object_ownercheck(ExtensionRelationId, extensionOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EXTENSION, stmt->extname); @@ -3229,7 +3229,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, &relation, AccessShareLock, false); /* Permission check: must own extension */ - if (!pg_extension_ownercheck(extension.objectId, GetUserId())) + if (!object_ownercheck(ExtensionRelationId, extension.objectId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EXTENSION, stmt->extname); diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 91f4dd30de..e6e6d128d1 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -358,7 +358,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) srvId = form->oid; /* Must be owner */ - if (!pg_foreign_server_ownercheck(srvId, GetUserId())) + if (!object_ownercheck(ForeignServerRelationId, srvId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER, NameStr(form->srvname)); @@ -998,7 +998,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt) /* * Only owner or a superuser can ALTER a SERVER. */ - if (!pg_foreign_server_ownercheck(srvId, GetUserId())) + if (!object_ownercheck(ForeignServerRelationId, srvId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER, stmt->servername); @@ -1076,7 +1076,7 @@ user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername) { Oid curuserid = GetUserId(); - if (!pg_foreign_server_ownercheck(serverid, curuserid)) + if (!object_ownercheck(ForeignServerRelationId, serverid, curuserid)) { if (umuserid == curuserid) { diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 1f820c93e9..3645216c4b 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1377,7 +1377,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) procForm = (Form_pg_proc) GETSTRUCT(tup); /* Permission check: must own function */ - if (!pg_proc_ownercheck(funcOid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, funcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, stmt->objtype, NameListToString(stmt->func->objname)); @@ -1554,8 +1554,8 @@ CreateCast(CreateCastStmt *stmt) TypeNameToString(stmt->targettype)))); /* Permission check */ - if (!pg_type_ownercheck(sourcetypeid, GetUserId()) - && !pg_type_ownercheck(targettypeid, GetUserId())) + if (!object_ownercheck(TypeRelationId, sourcetypeid, GetUserId()) + && !object_ownercheck(TypeRelationId, targettypeid, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of type %s or type %s", @@ -1838,7 +1838,7 @@ CreateTransform(CreateTransformStmt *stmt) errmsg("data type %s is a domain", TypeNameToString(stmt->type_name)))); - if (!pg_type_ownercheck(typeid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typeid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid); aclresult = pg_type_aclcheck(typeid, GetUserId(), ACL_USAGE); @@ -1861,7 +1861,7 @@ CreateTransform(CreateTransformStmt *stmt) { fromsqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->fromsql, false); - if (!pg_proc_ownercheck(fromsqlfuncid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, fromsqlfuncid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->fromsql->objname)); aclresult = pg_proc_aclcheck(fromsqlfuncid, GetUserId(), ACL_EXECUTE); @@ -1887,7 +1887,7 @@ CreateTransform(CreateTransformStmt *stmt) { tosqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->tosql, false); - if (!pg_proc_ownercheck(tosqlfuncid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, tosqlfuncid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->tosql->objname)); aclresult = pg_proc_aclcheck(tosqlfuncid, GetUserId(), ACL_EXECUTE); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 659e189549..aadd67b07f 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -27,7 +27,9 @@ #include "catalog/indexing.h" #include "catalog/pg_am.h" #include "catalog/pg_constraint.h" +#include "catalog/pg_database.h" #include "catalog/pg_inherits.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_opfamily.h" #include "catalog/pg_tablespace.h" @@ -2790,7 +2792,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, errmsg("\"%s\" is not an index", relation->relname))); /* Check permissions */ - if (!pg_class_ownercheck(relId, GetUserId())) + if (!object_ownercheck(RelationRelationId, relId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, relation->relname); /* Lock heap before index to avoid deadlock. */ @@ -2914,7 +2916,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, { objectOid = get_namespace_oid(objectName, false); - if (!pg_namespace_ownercheck(objectOid, GetUserId())) + if (!object_ownercheck(NamespaceRelationId, objectOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA, objectName); } @@ -2926,7 +2928,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("can only reindex the currently open database"))); - if (!pg_database_ownercheck(objectOid, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, objectOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, get_database_name(objectOid)); } @@ -3000,13 +3002,13 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, /* * The table can be reindexed if the user is superuser, the table * owner, or the database/schema owner (but in the latter case, only - * if it's not a shared relation). pg_class_ownercheck includes the + * if it's not a shared relation). object_ownercheck includes the * superuser case, and depending on objectKind we already know that * the user has permission to run REINDEX on this database or schema * per the permission checks at the beginning of this routine. */ if (classtuple->relisshared && - !pg_class_ownercheck(relid, GetUserId())) + !object_ownercheck(RelationRelationId, relid, GetUserId())) continue; /* diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 775553ec7b..c004e303e2 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -421,7 +421,7 @@ DefineOpClass(CreateOpClassStmt *stmt) #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Check we have ownership of the datatype */ - if (!pg_type_ownercheck(typeoid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typeoid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeoid); #endif @@ -513,11 +513,11 @@ DefineOpClass(CreateOpClassStmt *stmt) #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own operator and its underlying function */ - if (!pg_oper_ownercheck(operOid, GetUserId())) + if (!object_ownercheck(OperatorRelationId, operOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, get_opname(operOid)); funcOid = get_opcode(operOid); - if (!pg_proc_ownercheck(funcOid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, funcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, get_func_name(funcOid)); #endif @@ -542,7 +542,7 @@ DefineOpClass(CreateOpClassStmt *stmt) #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own function */ - if (!pg_proc_ownercheck(funcOid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, funcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, get_func_name(funcOid)); #endif @@ -570,7 +570,7 @@ DefineOpClass(CreateOpClassStmt *stmt) #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Check we have ownership of the datatype */ - if (!pg_type_ownercheck(storageoid, GetUserId())) + if (!object_ownercheck(TypeRelationId, storageoid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, storageoid); #endif break; @@ -930,11 +930,11 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own operator and its underlying function */ - if (!pg_oper_ownercheck(operOid, GetUserId())) + if (!object_ownercheck(OperatorRelationId, operOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, get_opname(operOid)); funcOid = get_opcode(operOid); - if (!pg_proc_ownercheck(funcOid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, funcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, get_func_name(funcOid)); #endif @@ -964,7 +964,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own function */ - if (!pg_proc_ownercheck(funcOid, GetUserId())) + if (!object_ownercheck(ProcedureRelationId, funcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, get_func_name(funcOid)); #endif diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index a5924d7d56..a2d7ae89d7 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -481,7 +481,7 @@ AlterOperator(AlterOperatorStmt *stmt) } /* Check permissions. Must be owner. */ - if (!pg_oper_ownercheck(oprId, GetUserId())) + if (!object_ownercheck(OperatorRelationId, oprId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR, NameStr(oprForm->oprname)); diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index d9dff9ecaa..4635a320b7 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -79,7 +79,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid, relkind = classform->relkind; /* Must own relation. */ - if (!pg_class_ownercheck(relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), rv->relname); /* No system table modifications unless explicitly allowed. */ diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 4a093f45d8..96a524be36 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -134,7 +134,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) /* This is currently pointless, since we already checked superuser */ #ifdef NOT_USED - if (!pg_language_ownercheck(oldform->oid, languageOwner)) + if (!object_ownercheck(LanguageRelationId, oldform->oid, languageOwner)) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_LANGUAGE, languageName); #endif diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index a8b75eb1be..8428e9e7b2 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -1394,7 +1394,7 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) pubform = (Form_pg_publication) GETSTRUCT(tup); /* must be owner */ - if (!pg_publication_ownercheck(pubform->oid, GetUserId())) + if (!object_ownercheck(PublicationRelationId, pubform->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION, stmt->pubname); @@ -1764,7 +1764,7 @@ PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, ObjectAddress obj; /* Must be owner of the table or superuser. */ - if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); @@ -1905,7 +1905,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) AclResult aclresult; /* Must be owner */ - if (!pg_publication_ownercheck(form->oid, GetUserId())) + if (!object_ownercheck(PublicationRelationId, form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION, NameStr(form->pubname)); diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 1346104973..3005a059e8 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -254,7 +254,7 @@ RenameSchema(const char *oldname, const char *newname) errmsg("schema \"%s\" already exists", newname))); /* must be owner */ - if (!pg_namespace_ownercheck(nspOid, GetUserId())) + if (!object_ownercheck(NamespaceRelationId, nspOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA, oldname); @@ -364,7 +364,7 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) AclResult aclresult; /* Otherwise, must be owner of the existing object */ - if (!pg_namespace_ownercheck(nspForm->oid, GetUserId())) + if (!object_ownercheck(NamespaceRelationId, nspForm->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA, NameStr(nspForm->nspname)); diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index 55216d2891..9cfd55d6fc 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -138,7 +138,7 @@ CreateStatistics(CreateStatsStmt *stmt) errdetail_relkind_not_supported(rel->rd_rel->relkind))); /* You must own the relation to create stats on it */ - if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner)) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(rel), stxowner)) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); @@ -665,7 +665,7 @@ AlterStatistics(AlterStatsStmt *stmt) elog(ERROR, "cache lookup failed for extended statistics object %u", stxoid); /* Must be owner of the existing statistics object */ - if (!pg_statistics_object_ownercheck(stxoid, GetUserId())) + if (!object_ownercheck(StatisticExtRelationId, stxoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_STATISTIC_EXT, NameListToString(stmt->defnames)); diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index f0cec2ad5e..d673557ea4 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1032,7 +1032,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, subid = form->oid; /* must be owner */ - if (!pg_subscription_ownercheck(subid, GetUserId())) + if (!object_ownercheck(SubscriptionRelationId, subid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION, stmt->subname); @@ -1418,7 +1418,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) subid = form->oid; /* must be owner */ - if (!pg_subscription_ownercheck(subid, GetUserId())) + if (!object_ownercheck(SubscriptionRelationId, subid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION, stmt->subname); @@ -1709,7 +1709,7 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) if (form->subowner == newOwnerId) return; - if (!pg_subscription_ownercheck(form->oid, GetUserId())) + if (!object_ownercheck(SubscriptionRelationId, form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION, NameStr(form->subname)); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fc4bd0de91..6804c7a859 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1572,8 +1572,8 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, state->expected_relkind); /* Allow DROP to either table owner or schema owner */ - if (!pg_class_ownercheck(relOid, GetUserId()) && - !pg_namespace_ownercheck(classform->relnamespace, GetUserId())) + if (!object_ownercheck(RelationRelationId, relOid, GetUserId()) && + !object_ownercheck(NamespaceRelationId, classform->relnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(classform->relkind), rel->relname); @@ -1877,7 +1877,7 @@ ExecuteTruncateGuts(List *explicit_rels, seq_rel = relation_open(seq_relid, AccessExclusiveLock); /* This check must match AlterSequence! */ - if (!pg_class_ownercheck(seq_relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, seq_relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SEQUENCE, RelationGetRelationName(seq_rel)); @@ -2514,7 +2514,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, * We should have an UNDER permission flag for this, but for now, * demand that creator of a child table own the parent. */ - if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(relation->rd_rel->relkind), RelationGetRelationName(relation)); @@ -3418,7 +3418,7 @@ renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing) /* * permissions checking. only the owner of a class can change its schema. */ - if (!pg_class_ownercheck(myrelid, GetUserId())) + if (!object_ownercheck(RelationRelationId, myrelid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(myrelid)), NameStr(classform->relname)); if (!allowSystemTableMods && IsSystemClass(myrelid, classform)) @@ -6307,7 +6307,7 @@ ATSimplePermissions(AlterTableType cmdtype, Relation rel, int allowed_targets) } /* Permissions checks */ - if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) + if (!object_ownercheck(RelationRelationId, RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); @@ -13828,7 +13828,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock AclResult aclresult; /* Otherwise, must be owner of the existing object */ - if (!pg_class_ownercheck(relationOid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relationOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relationOid)), RelationGetRelationName(target_rel)); @@ -14618,7 +14618,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) * * Caller must be considered an owner on the table to move it. */ - if (!pg_class_ownercheck(relOid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relOid)), NameStr(relForm->relname)); @@ -16953,7 +16953,7 @@ RangeVarCallbackOwnsTable(const RangeVar *relation, errmsg("\"%s\" is not a table or materialized view", relation->relname))); /* Check permissions */ - if (!pg_class_ownercheck(relId, GetUserId())) + if (!object_ownercheck(RelationRelationId, relId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)), relation->relname); } @@ -16998,7 +16998,7 @@ RangeVarCallbackOwnsRelation(const RangeVar *relation, if (!HeapTupleIsValid(tuple)) /* should not happen */ elog(ERROR, "cache lookup failed for relation %u", relId); - if (!pg_class_ownercheck(relId, GetUserId())) + if (!object_ownercheck(RelationRelationId, relId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)), relation->relname); @@ -17034,7 +17034,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid, relkind = classform->relkind; /* Must own relation. */ - if (!pg_class_ownercheck(relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), rv->relname); /* No system table modifications unless explicitly allowed. */ diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 45b30ca566..b60cb712c1 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -446,7 +446,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) tablespaceoid = spcform->oid; /* Must be tablespace owner */ - if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId())) + if (!object_ownercheck(TableSpaceRelationId, tablespaceoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLESPACE, tablespacename); @@ -966,7 +966,7 @@ RenameTableSpace(const char *oldname, const char *newname) table_endscan(scan); /* Must be owner */ - if (!pg_tablespace_ownercheck(tspId, GetUserId())) + if (!object_ownercheck(TableSpaceRelationId, tspId, GetUserId())) aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_TABLESPACE, oldname); /* Validate new name */ @@ -1051,7 +1051,7 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) tablespaceoid = ((Form_pg_tablespace) GETSTRUCT(tup))->oid; /* Must be owner of the existing object */ - if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId())) + if (!object_ownercheck(TableSpaceRelationId, tablespaceoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLESPACE, stmt->tablespacename); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index e64145e710..df40809282 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -1445,7 +1445,7 @@ RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid, errdetail_relkind_not_supported(form->relkind))); /* you must own the table to rename one of its triggers */ - if (!pg_class_ownercheck(relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), rv->relname); if (!allowSystemTableMods && IsSystemClass(relid, form)) ereport(ERROR, diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 4cc4e3c00f..365bfd30fd 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -510,7 +510,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) dictId); /* must be owner */ - if (!pg_ts_dict_ownercheck(dictId, GetUserId())) + if (!object_ownercheck(TSDictionaryRelationId, dictId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TSDICTIONARY, NameListToString(stmt->dictname)); @@ -1124,7 +1124,7 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid; /* must be owner */ - if (!pg_ts_config_ownercheck(cfgId, GetUserId())) + if (!object_ownercheck(TSConfigRelationId, cfgId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TSCONFIGURATION, NameListToString(stmt->cfgname)); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index b7c3dded17..b7e0194d23 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -525,28 +525,28 @@ DefineType(ParseState *pstate, List *names, List *parameters) * findTypeInputFunction et al, where they could be shared by AlterType. */ #ifdef NOT_USED - if (inputOid && !pg_proc_ownercheck(inputOid, GetUserId())) + if (inputOid && !object_ownercheck(ProcedureRelationId, inputOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(inputName)); - if (outputOid && !pg_proc_ownercheck(outputOid, GetUserId())) + if (outputOid && !object_ownercheck(ProcedureRelationId, outputOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(outputName)); - if (receiveOid && !pg_proc_ownercheck(receiveOid, GetUserId())) + if (receiveOid && !object_ownercheck(ProcedureRelationId, receiveOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(receiveName)); - if (sendOid && !pg_proc_ownercheck(sendOid, GetUserId())) + if (sendOid && !object_ownercheck(ProcedureRelationId, sendOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(sendName)); - if (typmodinOid && !pg_proc_ownercheck(typmodinOid, GetUserId())) + if (typmodinOid && !object_ownercheck(ProcedureRelationId, typmodinOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(typmodinName)); - if (typmodoutOid && !pg_proc_ownercheck(typmodoutOid, GetUserId())) + if (typmodoutOid && !object_ownercheck(ProcedureRelationId, typmodoutOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(typmodoutName)); - if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId())) + if (analyzeOid && !object_ownercheck(ProcedureRelationId, analyzeOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(analyzeName)); - if (subscriptOid && !pg_proc_ownercheck(subscriptOid, GetUserId())) + if (subscriptOid && !object_ownercheck(ProcedureRelationId, subscriptOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(subscriptName)); #endif @@ -1318,7 +1318,7 @@ checkEnumOwner(HeapTuple tup) format_type_be(typTup->oid)))); /* Permission check: must own type */ - if (!pg_type_ownercheck(typTup->oid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typTup->oid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); } @@ -3430,7 +3430,7 @@ checkDomainOwner(HeapTuple tup) format_type_be(typTup->oid)))); /* Permission check: must own type */ - if (!pg_type_ownercheck(typTup->oid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typTup->oid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); } @@ -3618,7 +3618,7 @@ RenameType(RenameStmt *stmt) typTup = (Form_pg_type) GETSTRUCT(tup); /* check permissions on type */ - if (!pg_type_ownercheck(typeOid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typeOid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeOid); /* ALTER DOMAIN used on a non-domain? */ @@ -3741,7 +3741,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) if (!superuser()) { /* Otherwise, must be owner of the existing object */ - if (!pg_type_ownercheck(typTup->oid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typTup->oid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); /* Must be able to become new owner */ @@ -3916,7 +3916,7 @@ AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved) Oid elemOid; /* check permissions on type */ - if (!pg_type_ownercheck(typeOid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typeOid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeOid); /* don't allow direct alteration of array types */ @@ -4277,7 +4277,7 @@ AlterType(AlterTypeStmt *stmt) } else { - if (!pg_type_ownercheck(typeOid, GetUserId())) + if (!object_ownercheck(TypeRelationId, typeOid, GetUserId())) aclcheck_error_type(ACLCHECK_NOT_OWNER, typeOid); } diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 04a18d4a42..2369cc600c 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -956,7 +956,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt) * If no role is specified, then this is effectively the same as * ALTER DATABASE ... SET, so use the same permission check. */ - if (!pg_database_ownercheck(databaseid, GetUserId())) + if (!object_ownercheck(DatabaseRelationId, databaseid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, stmt->database); } @@ -1586,7 +1586,7 @@ AddRoleMems(const char *rolename, Oid roleid, * The charter of pg_database_owner is to have exactly one, implicit, * situation-dependent member. There's no technical need for this * restriction. (One could lift it and take the further step of making - * pg_database_ownercheck() equivalent to has_privs_of_role(roleid, + * object_ownercheck(DatabaseRelationId, ...) equivalent to has_privs_of_role(roleid, * ROLE_PG_DATABASE_OWNER), in which case explicit, situation-independent * members could act as the owner of any database.) */ diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 7ccde07de9..3c8ea21475 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -565,14 +565,14 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options) * * We allow the user to vacuum or analyze a table if he is superuser, the * table owner, or the database owner (but in the latter case, only if - * it's not a shared relation). pg_class_ownercheck includes the + * it's not a shared relation). object_ownercheck includes the * superuser case. * * Note we choose to treat permissions failure as a WARNING and keep * trying to vacuum or analyze the rest of the DB --- is this appropriate? */ - if (pg_class_ownercheck(relid, GetUserId()) || - (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared)) + if (object_ownercheck(RelationRelationId, relid, GetUserId()) || + (object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared)) return true; relname = NameStr(reltuple->relname); diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index 106fdcdf81..c6e1e88dee 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -43,6 +43,7 @@ #include #include "access/xact.h" +#include "catalog/pg_largeobject_metadata.h" #include "libpq/be-fsstubs.h" #include "libpq/libpq-fs.h" #include "miscadmin.h" @@ -321,7 +322,7 @@ be_lo_unlink(PG_FUNCTION_ARGS) * relevant FDs. */ if (!lo_compat_privileges && - !pg_largeobject_ownercheck(lobjId, GetUserId())) + !object_ownercheck(LargeObjectMetadataRelationId, lobjId, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of large object %u", lobjId))); diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 09165b269b..db45d8a08b 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -279,7 +279,7 @@ DefineQueryRewrite(const char *rulename, /* * Check user has permission to apply rules to this relation. */ - if (!pg_class_ownercheck(event_relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, event_relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(event_relation->rd_rel->relkind), RelationGetRelationName(event_relation)); @@ -894,7 +894,7 @@ EnableDisableRule(Relation rel, const char *rulename, */ eventRelationOid = ruleform->ev_class; Assert(eventRelationOid == owningRel); - if (!pg_class_ownercheck(eventRelationOid, GetUserId())) + if (!object_ownercheck(RelationRelationId, eventRelationOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(eventRelationOid)), get_rel_name(eventRelationOid)); @@ -956,7 +956,7 @@ RangeVarCallbackForRenameRule(const RangeVar *rv, Oid relid, Oid oldrelid, rv->relname))); /* you must own the table to rename one of its rules */ - if (!pg_class_ownercheck(relid, GetUserId())) + if (!object_ownercheck(RelationRelationId, relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), rv->relname); ReleaseSysCache(tuple); diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 61c2eecaca..dc07157037 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -1427,9 +1427,9 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) */ if (!has_bypassrls_privilege(GetUserId()) && ((pk_rel->rd_rel->relrowsecurity && - !pg_class_ownercheck(pkrte->relid, GetUserId())) || + !object_ownercheck(RelationRelationId, pkrte->relid, GetUserId())) || (fk_rel->rd_rel->relrowsecurity && - !pg_class_ownercheck(fkrte->relid, GetUserId())))) + !object_ownercheck(RelationRelationId, fkrte->relid, GetUserId())))) return false; /*---------- diff --git a/src/backend/utils/misc/rls.c b/src/backend/utils/misc/rls.c index d15880670f..75d42c9ec3 100644 --- a/src/backend/utils/misc/rls.c +++ b/src/backend/utils/misc/rls.c @@ -95,7 +95,7 @@ check_enable_rls(Oid relid, Oid checkAsUser, bool noError) * Return RLS_NONE_ENV to indicate that this decision depends on the * environment (in this case, the user_id). */ - amowner = pg_class_ownercheck(relid, user_id); + amowner = object_ownercheck(RelationRelationId, relid, user_id); if (amowner) { /* diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 9a4df3a5da..79eff59768 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -306,28 +306,7 @@ extern void removeExtObjInitPriv(Oid objoid, Oid classoid); /* ownercheck routines just return true (owner) or false (not) */ -extern bool pg_class_ownercheck(Oid class_oid, Oid roleid); -extern bool pg_type_ownercheck(Oid type_oid, Oid roleid); -extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid); -extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid); -extern bool pg_language_ownercheck(Oid lan_oid, Oid roleid); -extern bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid); -extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid); -extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid); -extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid); -extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid); -extern bool pg_database_ownercheck(Oid db_oid, Oid roleid); -extern bool pg_collation_ownercheck(Oid coll_oid, Oid roleid); -extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid); -extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid); -extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid); -extern bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid); -extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid); -extern bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid); -extern bool pg_extension_ownercheck(Oid ext_oid, Oid roleid); -extern bool pg_publication_ownercheck(Oid pub_oid, Oid roleid); -extern bool pg_subscription_ownercheck(Oid sub_oid, Oid roleid); -extern bool pg_statistics_object_ownercheck(Oid stat_oid, Oid roleid); +extern bool object_ownercheck(Oid classid, Oid objectid, Oid roleid); extern bool has_createrole_privilege(Oid roleid); extern bool has_bypassrls_privilege(Oid roleid);