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);