refactor ownercheck and aclcheck functions
These patches take the dozens of mostly-duplicate pg_foo_ownercheck()
and pg_foo_aclcheck() functions and replace (most of) them by common
functions that are driven by the ObjectProperty table. All the required
information is already in that table.
This is similar to the consolidation of the drop-by-OID functions that
we did a while ago (b1d32d3e3230f00b5baba08f75b4f665c7d6dac6).
Attachments:
0001-Refactor-ownercheck-functions.patchtext/plain; charset=UTF-8; name=0001-Refactor-ownercheck-functions.patchDownload
From fc98a7bdb9f2d1a47f67305c78aecc385cc10f21 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 14 Oct 2022 09:16:51 +0200
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.
I kept a few pg_foo_ownercheck() around as thin wrappers because they
are widely used through the code. And there are also a couple that
don't work via the generic function, so those stay as is.
---
src/backend/catalog/aclchk.c | 517 ++----------------------
src/backend/catalog/objectaddress.c | 92 +----
src/backend/commands/collationcmds.c | 2 +-
src/backend/commands/event_trigger.c | 4 +-
src/backend/commands/foreigncmds.c | 6 +-
src/backend/commands/proclang.c | 2 +-
src/backend/commands/publicationcmds.c | 4 +-
src/backend/commands/statscmds.c | 2 +-
src/backend/commands/subscriptioncmds.c | 6 +-
src/backend/commands/tablespace.c | 6 +-
src/backend/commands/tsearchcmds.c | 4 +-
src/include/utils/acl.h | 22 +-
12 files changed, 71 insertions(+), 596 deletions(-)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index aa5a2ed9483e..d67d3b522cef 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,25 +5112,30 @@ 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;
Oid ownerId;
+ bool isnull;
/* Superusers bypass all permission checking. */
if (superuser_arg(roleid))
return true;
- tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
+ tuple = SearchSysCache1(get_object_catcache_oid(classid), ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_TABLE),
- errmsg("relation with OID %u does not exist", class_oid)));
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
- ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
+ ownerId = DatumGetObjectId(SysCacheGetAttr(get_object_catcache_oid(classid),
+ tuple,
+ get_object_attnum_owner(classid),
+ &isnull));
+ Assert(!isnull);
ReleaseSysCache(tuple);
@@ -5137,107 +5143,43 @@ pg_class_ownercheck(Oid class_oid, Oid roleid)
}
/*
- * Ownership check for a type (specified by OID).
+ * Wrapper functions for commonly used cases
*/
+
bool
-pg_type_ownercheck(Oid type_oid, Oid roleid)
+pg_class_ownercheck(Oid class_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 object_ownercheck(RelationRelationId, class_oid, roleid);
+}
- return has_privs_of_role(roleid, ownerId);
+bool
+pg_type_ownercheck(Oid type_oid, Oid roleid)
+{
+ return object_ownercheck(TypeRelationId, type_oid, roleid);
}
-/*
- * 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);
+ return object_ownercheck(OperatorRelationId, oper_oid, roleid);
}
-/*
- * 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);
+ return object_ownercheck(ProcedureRelationId, proc_oid, roleid);
}
-/*
- * Ownership check for a procedural language (specified by OID)
- */
bool
-pg_language_ownercheck(Oid lan_oid, Oid roleid)
+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(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 object_ownercheck(NamespaceRelationId, nsp_oid, roleid);
+}
- return has_privs_of_role(roleid, ownerId);
+bool
+pg_database_ownercheck(Oid db_oid, Oid roleid)
+{
+ return object_ownercheck(DatabaseRelationId, db_oid, roleid);
}
/*
@@ -5286,326 +5228,6 @@ pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
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).
*/
@@ -5648,85 +5270,6 @@ pg_extension_ownercheck(Oid ext_oid, Oid roleid)
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);
-
- return has_privs_of_role(roleid, ownerId);
-}
-
/*
* Check whether specified role has CREATEROLE privilege (or is a superuser)
*
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 284ca55469e0..80c9110fd1a8 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2443,11 +2443,6 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
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:
@@ -2481,27 +2476,32 @@ 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_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))
+ case OBJECT_OPCLASS:
+ case OBJECT_OPFAMILY:
+ 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;
@@ -2510,36 +2510,6 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
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))
- aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
- NameListToString(castNode(List, object)));
- break;
case OBJECT_LARGEOBJECT:
if (!lo_compat_privileges &&
!pg_largeobject_ownercheck(address.objectId, roleid))
@@ -2565,16 +2535,6 @@ 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));
@@ -2584,21 +2544,6 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
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 +2575,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/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index fcfc02d2aede..25c1e485c458 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -365,7 +365,7 @@ AlterCollation(AlterCollationStmt *stmt)
rel = table_open(CollationRelationId, RowExclusiveLock);
collOid = get_collation_oid(stmt->collname, false);
- 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/event_trigger.c b/src/backend/commands/event_trigger.c
index 441f29d684ff..7ed9c80fc63c 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/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 91f4dd30de18..e6e6d128d11a 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/proclang.c b/src/backend/commands/proclang.c
index 4a093f45d85a..96a524be36aa 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 a8b75eb1be8b..3d0f712a4faf 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);
@@ -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/statscmds.c b/src/backend/commands/statscmds.c
index 55216d28916b..0d87318e0233 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -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 8fb89a9392c8..a69b9a38bdcf 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);
@@ -1413,7 +1413,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);
@@ -1704,7 +1704,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/tablespace.c b/src/backend/commands/tablespace.c
index b69ff37dbbdc..12c7993b15aa 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/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 4cc4e3c00f8e..365bfd30fdfe 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/include/utils/acl.h b/src/include/utils/acl.h
index 9a4df3a5dacc..bf461f24fde7 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -306,28 +306,20 @@ extern void removeExtObjInitPriv(Oid objoid, Oid classoid);
/* ownercheck routines just return true (owner) or false (not) */
+extern bool object_ownercheck(Oid classid, Oid objectid, Oid roleid);
+
+/* wrapper functions for commonly used cases */
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);
+
+/* special cases */
+extern bool pg_largeobject_ownercheck(Oid lobj_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 has_createrole_privilege(Oid roleid);
extern bool has_bypassrls_privilege(Oid roleid);
--
2.37.3
0002-Refactor-aclcheck-functions.patchtext/plain; charset=UTF-8; name=0002-Refactor-aclcheck-functions.patchDownload
From 15c6a6dd5ab08027a324eeb11c0a9b519c4b3d94 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 14 Oct 2022 09:16:51 +0200
Subject: [PATCH] Refactor aclcheck functions
Instead of dozens of mostly-duplicate pg_foo_aclcheck() functions,
write one common function object_aclcheck() 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 ACL column.
I kept a few pg_foo_aclcheck() around as thin wrappers because they
are widely used through the code. And there are also a few that don't
work via the generic function, so those stay as is.
I also changed most pg_foo_aclmask() functions to static functions,
since they are not used outside of aclchk.c.
---
contrib/dblink/dblink.c | 2 +-
src/backend/catalog/aclchk.c | 601 +++++++---------------------
src/backend/commands/foreigncmds.c | 10 +-
src/backend/commands/functioncmds.c | 6 +-
src/backend/utils/adt/acl.c | 52 +--
src/backend/utils/fmgr/fmgr.c | 2 +-
src/include/utils/acl.h | 47 +--
7 files changed, 188 insertions(+), 532 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 9eef417c47b7..f8b017fd3a29 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -2838,7 +2838,7 @@ get_connect_string(const char *servername)
fdw = GetForeignDataWrapper(fdwid);
/* Check permissions, user must have usage on the server. */
- aclresult = pg_foreign_server_aclcheck(serverid, userid, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, userid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, foreign_server->servername);
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index d67d3b522cef..9e8ec306f639 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -139,8 +139,26 @@ static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
Oid objectId, Oid grantorId,
ObjectType objtype, const char *objname,
AttrNumber att_number, const char *colname);
-static AclMode pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum,
+static AclMode pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum,
Oid roleid, AclMode mask, AclMaskHow how);
+static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
+ Oid roleid, AclMode mask, AclMaskHow how);
+static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
+ Oid roleid, AclMode mask,
+ AclMaskHow how, bool *is_missing);
+static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid,
+ AclMode mask, AclMaskHow how,
+ bool *is_missing);
+static AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
+ AclMode mask, AclMaskHow how, Snapshot snapshot);
+static AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid,
Acl *new_acl);
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid,
@@ -3787,47 +3805,47 @@ aclcheck_error_type(AclResult aclerr, Oid typeOid)
* Relay for the various pg_*_mask routines depending on object kind
*/
static AclMode
-pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
+pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how)
{
switch (objtype)
{
case OBJECT_COLUMN:
return
- pg_class_aclmask(table_oid, roleid, mask, how) |
- pg_attribute_aclmask(table_oid, attnum, roleid, mask, how);
+ pg_class_aclmask(object_oid, roleid, mask, how) |
+ pg_attribute_aclmask(object_oid, attnum, roleid, mask, how);
case OBJECT_TABLE:
case OBJECT_SEQUENCE:
- return pg_class_aclmask(table_oid, roleid, mask, how);
+ return pg_class_aclmask(object_oid, roleid, mask, how);
case OBJECT_DATABASE:
- return pg_database_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(DatabaseRelationId, object_oid, roleid, mask, how);
case OBJECT_FUNCTION:
- return pg_proc_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ProcedureRelationId, object_oid, roleid, mask, how);
case OBJECT_LANGUAGE:
- return pg_language_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(LanguageRelationId, object_oid, roleid, mask, how);
case OBJECT_LARGEOBJECT:
- return pg_largeobject_aclmask_snapshot(table_oid, roleid,
+ return pg_largeobject_aclmask_snapshot(object_oid, roleid,
mask, how, NULL);
case OBJECT_PARAMETER_ACL:
- return pg_parameter_acl_aclmask(table_oid, roleid, mask, how);
+ return pg_parameter_acl_aclmask(object_oid, roleid, mask, how);
case OBJECT_SCHEMA:
- return pg_namespace_aclmask(table_oid, roleid, mask, how);
+ return pg_namespace_aclmask(object_oid, roleid, mask, how);
case OBJECT_STATISTIC_EXT:
elog(ERROR, "grantable rights not supported for statistics objects");
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
case OBJECT_TABLESPACE:
- return pg_tablespace_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(TableSpaceRelationId, object_oid, roleid, mask, how);
case OBJECT_FDW:
- return pg_foreign_data_wrapper_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ForeignDataWrapperRelationId, object_oid, roleid, mask, how);
case OBJECT_FOREIGN_SERVER:
- return pg_foreign_server_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ForeignServerRelationId, object_oid, roleid, mask, how);
case OBJECT_EVENT_TRIGGER:
elog(ERROR, "grantable rights not supported for event triggers");
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
case OBJECT_TYPE:
- return pg_type_aclmask(table_oid, roleid, mask, how);
+ return pg_type_aclmask(object_oid, roleid, mask, how);
default:
elog(ERROR, "unrecognized objtype: %d",
(int) objtype);
@@ -3849,14 +3867,72 @@ pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
*/
/*
- * Exported routine for examining a user's privileges for a column
+ * Generic routine for examining a user's privileges for an object
+ */
+static AclMode
+object_aclmask(Oid classid, Oid objectid, Oid roleid,
+ AclMode mask, AclMaskHow how)
+{
+ AclMode result;
+ HeapTuple tuple;
+ Datum aclDatum;
+ bool isNull;
+ Acl *acl;
+ Oid ownerId;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return mask;
+
+ /*
+ * Get the objects's ACL from its catalog
+ */
+ tuple = SearchSysCache1(get_object_catcache_oid(classid), ObjectIdGetDatum(objectid));
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
+
+ ownerId = DatumGetObjectId(SysCacheGetAttr(get_object_catcache_oid(classid),
+ tuple,
+ get_object_attnum_owner(classid),
+ &isNull));
+ Assert(!isNull);
+
+ aclDatum = SysCacheGetAttr(get_object_catcache_oid(classid), tuple, get_object_attnum_acl(classid),
+ &isNull);
+ if (isNull)
+ {
+ /* No ACL, so build default ACL */
+ acl = acldefault(get_object_type(classid, objectid), ownerId);
+ aclDatum = (Datum) 0;
+ }
+ else
+ {
+ /* detoast ACL if necessary */
+ acl = DatumGetAclP(aclDatum);
+ }
+
+ result = aclmask(acl, roleid, ownerId, mask, how);
+
+ /* if we have a detoasted copy, free it */
+ if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
+ pfree(acl);
+
+ ReleaseSysCache(tuple);
+
+ return result;
+}
+
+/*
+ * Routine for examining a user's privileges for a column
*
* Note: this considers only privileges granted specifically on the column.
* It is caller's responsibility to take relation-level privileges into account
* as appropriate. (For the same reason, we have no special case for
* superuser-ness here.)
*/
-AclMode
+static AclMode
pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how)
{
@@ -3865,12 +3941,12 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a column
+ * Routine for examining a user's privileges for a column
*
* Does the bulk of the work for pg_attribute_aclmask(), and allows other
* callers to avoid the missing attribute ERROR when is_missing is non-NULL.
*/
-AclMode
+static AclMode
pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how, bool *is_missing)
{
@@ -3983,12 +4059,12 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a table
+ * Routine for examining a user's privileges for a table
*
* Does the bulk of the work for pg_class_aclmask(), and allows other
* callers to avoid the missing relation ERROR when is_missing is non-NULL.
*/
-AclMode
+static AclMode
pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
AclMaskHow how, bool *is_missing)
{
@@ -4104,64 +4180,10 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
}
/*
- * Exported routine for examining a user's privileges for a database
- */
-AclMode
-pg_database_aclmask(Oid db_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the database's ACL from pg_database
- */
- 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)));
-
- ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
-
- aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_DATABASE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a configuration
+ * Routine for examining a user's privileges for a configuration
* parameter (GUC), identified by GUC name.
*/
-AclMode
+static AclMode
pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4222,10 +4244,10 @@ pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
}
/*
- * Exported routine for examining a user's privileges for a configuration
+ * Routine for examining a user's privileges for a configuration
* parameter (GUC), identified by the OID of its pg_parameter_acl entry.
*/
-AclMode
+static AclMode
pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4273,115 +4295,7 @@ pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
}
/*
- * Exported routine for examining a user's privileges for a function
- */
-AclMode
-pg_proc_aclmask(Oid proc_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the function's ACL from pg_proc
- */
- 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;
-
- aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FUNCTION, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a language
- */
-AclMode
-pg_language_aclmask(Oid lang_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the language's ACL from pg_language
- */
- tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language with OID %u does not exist", lang_oid)));
-
- ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
-
- aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_LANGUAGE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a largeobject
+ * Routine for examining a user's privileges for a largeobject
*
* When a large object is opened for reading, it is opened relative to the
* caller's snapshot, but when it is opened for writing, a current
@@ -4392,7 +4306,7 @@ pg_language_aclmask(Oid lang_oid, Oid roleid,
* snapshot, since all we do with the snapshot argument is pass it through
* to systable_beginscan().
*/
-AclMode
+static AclMode
pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
AclMode mask, AclMaskHow how,
Snapshot snapshot)
@@ -4463,9 +4377,9 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a namespace
+ * Routine for examining a user's privileges for a namespace
*/
-AclMode
+static AclMode
pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
@@ -4555,189 +4469,9 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a tablespace
+ * Routine for examining a user's privileges for a type.
*/
-AclMode
-pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the tablespace's ACL from pg_tablespace
- */
- tuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace with OID %u does not exist", spc_oid)));
-
- ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
-
- aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple,
- Anum_pg_tablespace_spcacl,
- &isNull);
-
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_TABLESPACE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a foreign
- * data wrapper
- */
-AclMode
-pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- Form_pg_foreign_data_wrapper fdwForm;
-
- /* Bypass permission checks for superusers */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Must get the FDW's tuple from pg_foreign_data_wrapper
- */
- tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdw_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("foreign-data wrapper with OID %u does not exist",
- fdw_oid)));
- fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
-
- /*
- * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
- */
- ownerId = fdwForm->fdwowner;
-
- aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
- Anum_pg_foreign_data_wrapper_fdwacl, &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FDW, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast rel's ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a foreign
- * server.
- */
-AclMode
-pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- Form_pg_foreign_server srvForm;
-
- /* Bypass permission checks for superusers */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Must get the FDW's tuple from pg_foreign_data_wrapper
- */
- 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)));
- srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
-
- /*
- * Normal case: get the foreign server's ACL from pg_foreign_server
- */
- ownerId = srvForm->srvowner;
-
- aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
- Anum_pg_foreign_server_srvacl, &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FOREIGN_SERVER, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast rel's ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a type.
- */
-AclMode
+static AclMode
pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4811,6 +4545,40 @@ pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
return result;
}
+/*
+ * Exported generic routine for checking a user's access privileges to an object
+ */
+AclResult
+object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
+{
+ if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
+ return ACLCHECK_OK;
+ else
+ return ACLCHECK_NO_PRIV;
+}
+
+/*
+ * Wrapper functions for commonly used cases
+ */
+
+AclResult
+pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
+{
+ return object_aclcheck(DatabaseRelationId, db_oid, roleid, mode);
+}
+
+AclResult
+pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
+{
+ return object_aclcheck(ProcedureRelationId, proc_oid, roleid, mode);
+}
+
+AclResult
+pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
+{
+ return object_aclcheck(TableSpaceRelationId, spc_oid, roleid, mode);
+}
+
/*
* Exported routine for checking a user's access privileges to a column
*
@@ -4973,18 +4741,6 @@ pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a database
- */
-AclResult
-pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
-{
- if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Exported routine for checking a user's access privileges to a configuration
* parameter (GUC), identified by GUC name.
@@ -4998,43 +4754,6 @@ pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a configuration
- * parameter (GUC), identified by the OID of its pg_parameter_acl entry.
- */
-AclResult
-pg_parameter_acl_aclcheck(Oid acl_oid, Oid roleid, AclMode mode)
-{
- if (pg_parameter_acl_aclmask(acl_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a function
- */
-AclResult
-pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
-{
- if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a language
- */
-AclResult
-pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
-{
- if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Exported routine for checking a user's access privileges to a largeobject
*/
@@ -5061,44 +4780,6 @@ pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a tablespace
- */
-AclResult
-pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
-{
- if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a foreign
- * data wrapper
- */
-AclResult
-pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode)
-{
- if (pg_foreign_data_wrapper_aclmask(fdw_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a foreign
- * server
- */
-AclResult
-pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode)
-{
- if (pg_foreign_server_aclmask(srv_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Exported routine for checking a user's access privileges to a type
*/
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index e6e6d128d11a..55b0be9e1d11 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -366,7 +366,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have USAGE privilege on foreign-data wrapper */
- aclresult = pg_foreign_data_wrapper_aclcheck(form->srvfdw, newOwnerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
{
ForeignDataWrapper *fdw = GetForeignDataWrapper(form->srvfdw);
@@ -891,7 +891,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
*/
fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdw->fdwid, ownerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdw->fdwid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FDW, fdw->fdwname);
@@ -1082,7 +1082,7 @@ user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
{
AclResult aclresult;
- aclresult = pg_foreign_server_aclcheck(serverid, curuserid, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, curuserid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, servername);
}
@@ -1433,7 +1433,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
* get the actual FDW for option validation etc.
*/
server = GetForeignServerByName(stmt->servername, false);
- aclresult = pg_foreign_server_aclcheck(server->serverid, ownerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
@@ -1492,7 +1492,7 @@ ImportForeignSchema(ImportForeignSchemaStmt *stmt)
/* Check that the foreign server exists and that we have USAGE on it */
server = GetForeignServerByName(stmt->server_name, false);
- aclresult = pg_foreign_server_aclcheck(server->serverid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index e6fcfc23b931..e006033bd845 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1111,7 +1111,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
if (languageStruct->lanpltrusted)
{
/* if trusted language, need USAGE privilege */
- aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(LanguageRelationId, languageOid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
NameStr(languageStruct->lanname));
@@ -1844,7 +1844,7 @@ CreateTransform(CreateTransformStmt *stmt)
*/
langid = get_language_oid(stmt->lang, false);
- aclresult = pg_language_aclcheck(langid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(LanguageRelationId, langid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE, stmt->lang);
@@ -2110,7 +2110,7 @@ ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic)
/* if trusted language, need USAGE privilege */
AclResult aclresult;
- aclresult = pg_language_aclcheck(codeblock->langOid, GetUserId(),
+ aclresult = object_aclcheck(LanguageRelationId, codeblock->langOid, GetUserId(),
ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 4fac402e5b64..01862e26a916 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -23,7 +23,11 @@
#include "catalog/pg_authid.h"
#include "catalog/pg_class.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_foreign_data_wrapper.h"
+#include "catalog/pg_foreign_server.h"
+#include "catalog/pg_language.h"
#include "catalog/pg_parameter_acl.h"
+#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/proclang.h"
@@ -3099,7 +3103,7 @@ has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3124,7 +3128,7 @@ has_foreign_data_wrapper_privilege_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3150,7 +3154,7 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3176,7 +3180,7 @@ has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3199,7 +3203,7 @@ has_foreign_data_wrapper_privilege_id_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3223,7 +3227,7 @@ has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3490,7 +3494,7 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3515,7 +3519,7 @@ has_language_privilege_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3541,7 +3545,7 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3567,7 +3571,7 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3590,7 +3594,7 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3614,7 +3618,7 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3874,7 +3878,7 @@ has_server_privilege_name_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3899,7 +3903,7 @@ has_server_privilege_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3925,7 +3929,7 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3951,7 +3955,7 @@ has_server_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3974,7 +3978,7 @@ has_server_privilege_id_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3998,7 +4002,7 @@ has_server_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4065,7 +4069,7 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4090,7 +4094,7 @@ has_tablespace_privilege_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4116,7 +4120,7 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4142,7 +4146,7 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4165,7 +4169,7 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4189,7 +4193,7 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index a9dd068095bf..b38bd1003ea0 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -2054,7 +2054,7 @@ CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
langStruct->lanvalidator)));
/* first validate that we have permissions to use the language */
- aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
+ aclresult = object_aclcheck(LanguageRelationId, procStruct->prolang, GetUserId(),
ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index bf461f24fde7..dac9993a0fbe 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -235,39 +235,18 @@ extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivi
extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
-extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
- Oid roleid, AclMode mask, AclMaskHow how);
-extern AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
- Oid roleid, AclMode mask,
- AclMaskHow how, bool *is_missing);
extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid,
- AclMode mask, AclMaskHow how,
- bool *is_missing);
-extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_parameter_aclmask(const char *name, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
- AclMode mask, AclMaskHow how, Snapshot snapshot);
-extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
+/* generic function */
+extern AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode);
+
+/* wrapper functions for commonly used cases */
+extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
+extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
+extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
+
+/* special cases */
extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
Oid roleid, AclMode mode);
extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
@@ -278,19 +257,11 @@ extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
AclMode mode, bool *is_missing);
-extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
extern AclResult pg_parameter_aclcheck(const char *name, Oid roleid,
AclMode mode);
-extern AclResult pg_parameter_acl_aclcheck(Oid acl_oid, Oid roleid,
- AclMode mode);
-extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
-extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
extern AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid,
AclMode mode, Snapshot snapshot);
extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
-extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
-extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode);
-extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode);
extern AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode);
extern void aclcheck_error(AclResult aclerr, ObjectType objtype,
--
2.37.3
On Fri, Oct 14, 2022 at 3:39 AM Peter Eisentraut <
peter.eisentraut@enterprisedb.com> wrote:
These patches take the dozens of mostly-duplicate pg_foo_ownercheck()
and pg_foo_aclcheck() functions and replace (most of) them by common
functions that are driven by the ObjectProperty table. All the required
information is already in that table.This is similar to the consolidation of the drop-by-OID functions that
we did a while ago (b1d32d3e3230f00b5baba08f75b4f665c7d6dac6).
Nice reduction in footprint!
I'd be inclined to remove the highly used ones as well. That way the
codebase would have more examples of object_ownercheck() for readers to
see. Seeing the existence of pg_FOO_ownercheck implies that a
pg_BAR_ownercheck might exist, and if BAR is missing they might be inclined
to re-add it.
If we do keep them, would it make sense to go the extra step and turn the
remaining six "regular" into static inline functions or even #define-s?
On 20.10.22 01:24, Corey Huinker wrote:
I'd be inclined to remove the highly used ones as well. That way the
codebase would have more examples of object_ownercheck() for readers to
see. Seeing the existence of pg_FOO_ownercheck implies that a
pg_BAR_ownercheck might exist, and if BAR is missing they might be
inclined to re-add it.
We do have several ownercheck and aclcheck functions that can't be
refactored into this framework right now, so we do have to keep some
special-purpose functions around anyway. I'm afraid converting all the
callers would blow up this patch quite a bit, but it could be done as a
follow-up patch.
If we do keep them, would it make sense to go the extra step and turn
the remaining six "regular" into static inline functions or even #define-s?
That could make sense.
Peter Eisentraut <peter.eisentraut@enterprisedb.com> wrote:
These patches take the dozens of mostly-duplicate pg_foo_ownercheck() and
pg_foo_aclcheck() functions and replace (most of) them by common functions
that are driven by the ObjectProperty table. All the required information is
already in that table.This is similar to the consolidation of the drop-by-OID functions that we did
a while ago (b1d32d3e3230f00b5baba08f75b4f665c7d6dac6).
I've reviewed this patch, as it's related to my patch [1] (In particular, it
reduces the size of my patch a little bit). I like the idea to reduce the
amount of (almost) copy & pasted code. I haven't found any problem in your
patch that would be worth mentioning, except that the 0001 part does not apply
to the current master branch.
--
Antonin Houska
Web: https://www.cybertec-postgresql.com
On 21.10.22 21:17, Peter Eisentraut wrote:
On 20.10.22 01:24, Corey Huinker wrote:
I'd be inclined to remove the highly used ones as well. That way the
codebase would have more examples of object_ownercheck() for readers
to see. Seeing the existence of pg_FOO_ownercheck implies that a
pg_BAR_ownercheck might exist, and if BAR is missing they might be
inclined to re-add it.We do have several ownercheck and aclcheck functions that can't be
refactored into this framework right now, so we do have to keep some
special-purpose functions around anyway. I'm afraid converting all the
callers would blow up this patch quite a bit, but it could be done as a
follow-up patch.If we do keep them, would it make sense to go the extra step and turn
the remaining six "regular" into static inline functions or even
#define-s?That could make sense.
After considering this again, I decided to brute-force this and get rid
of all the trivial wrapper functions and also several of the special
cases. That way, there is less confusion at the call sites about why
this or that style is used in a particular case. Also, it now makes
sure you can't accidentally use the generic functions when a particular
one should be used.
Attachments:
v2-0001-Refactor-ownercheck-functions.patchtext/plain; charset=UTF-8; name=v2-0001-Refactor-ownercheck-functions.patchDownload
From c461a8d3f8d7a2f0382b5152301764b8bc82ac91 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 8 Nov 2022 11:05:12 +0100
Subject: [PATCH v2 1/2] 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.
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 | 643 ++----------------------
src/backend/catalog/namespace.c | 2 +-
src/backend/catalog/objectaddress.c | 106 +---
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, 183 insertions(+), 806 deletions(-)
diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c
index 8a2ad9773d04..191ce72c231d 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 20b7d65b948f..7e386250ae94 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 f750b5ed9e90..0435598bd16c 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 aa5a2ed9483e..fac67748e6db 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;
- 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;
+ int cacheid;
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;
+ cacheid = get_object_catcache_oid(classid);
+ if (cacheid != -1)
+ {
+ HeapTuple tuple;
+ bool isnull;
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return true;
+ tuple = SearchSysCache1(get_object_catcache_oid(classid), 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)));
- 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 = DatumGetObjectId(SysCacheGetAttr(get_object_catcache_oid(classid),
+ tuple,
+ get_object_attnum_owner(classid),
+ &isnull));
+ Assert(!isnull);
- ownerId = ((Form_pg_subscription) GETSTRUCT(tuple))->subowner;
+ ReleaseSysCache(tuple);
+ }
+ else
+ {
+ /* for catalogs without an appropriate syscache */
- ReleaseSysCache(tuple);
+ Relation rel;
+ ScanKeyData entry[1];
+ SysScanDesc scan;
+ HeapTuple tuple;
+ bool isnull;
- return has_privs_of_role(roleid, ownerId);
-}
+ rel = table_open(classid, AccessShareLock);
-/*
- * Ownership check for a statistics object (specified by OID).
- */
-bool
-pg_statistics_object_ownercheck(Oid stat_oid, Oid roleid)
-{
- HeapTuple tuple;
- Oid ownerId;
+ ScanKeyInit(&entry[0],
+ get_object_attnum_oid(classid),
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(objectid));
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return true;
+ scan = systable_beginscan(rel,
+ get_object_oid_index(classid), true,
+ NULL, 1, entry);
- 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)));
+ 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 = ((Form_pg_statistic_ext) GETSTRUCT(tuple))->stxowner;
+ ownerId = DatumGetObjectId(heap_getattr(tuple,
+ get_object_attnum_owner(classid),
+ RelationGetDescr(rel),
+ &isnull));
+ Assert(!isnull);
- ReleaseSysCache(tuple);
+ 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 539df1da9493..1543f2abcd8d 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 284ca55469e0..c19aa143b522 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_SCHEMA:
- if (!pg_namespace_ownercheck(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_DATABASE:
+ case OBJECT_EVENT_TRIGGER:
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))
+ case OBJECT_PUBLICATION:
+ case OBJECT_SCHEMA:
+ 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:
+ case OBJECT_CONVERSION:
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 3947ad89806c..e6e794b6ff90 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 e03b98bcd2a5..69f43aa0ecbf 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 1976a373efa6..3b78a2f100d3 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 86fbc7fa019f..1753d67b612c 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 8abc2c3e0b0f..0d6a1228639d 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 26157eb4e3f5..389fc6a102cf 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 8d36b6648809..a3bdc5db0735 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 1a62e5dac5a3..722e94bbce04 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 91f4dd30de18..e6e6d128d11a 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 1f820c93e960..3645216c4b59 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 659e18954945..aadd67b07f5a 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 775553ec7be9..c004e303e282 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 a5924d7d564d..a2d7ae89d741 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 d9dff9ecaabf..4635a320b716 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 4a093f45d85a..96a524be36aa 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 a8b75eb1be8b..8428e9e7b220 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 1346104973f3..3005a059e823 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 55216d28916b..9cfd55d6fc73 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 f0cec2ad5e7a..d673557ea400 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 6007e10730a1..c6d518012d25 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 45b30ca566d2..b60cb712c1f6 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 e64145e710c8..df408092820c 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 4cc4e3c00f8e..365bfd30fdfe 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 b7c3dded1704..b7e0194d2367 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 04a18d4a425a..2369cc600c7c 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 7ccde07de9c9..3c8ea2147537 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 3e5cada7eb53..14f109a8972b 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -43,6 +43,7 @@
#include <unistd.h>
#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 09165b269b30..db45d8a08b22 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 61c2eecacaa4..dc07157037d4 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 d15880670f75..75d42c9ec3fb 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 9a4df3a5dacc..79eff5976890 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);
base-commit: bd95816f74ad4cad3d2a3c160be426358d6cea51
--
2.38.1
v2-0002-Refactor-aclcheck-functions.patchtext/plain; charset=UTF-8; name=v2-0002-Refactor-aclcheck-functions.patchDownload
From ef1122f4b64caaf3267bd493825f9c013bfe3965 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 8 Nov 2022 12:07:01 +0100
Subject: [PATCH v2 2/2] Refactor aclcheck functions
Instead of dozens of mostly-duplicate pg_foo_aclcheck() functions,
write one common function object_aclcheck() 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 ACL column.
There are a few pg_foo_aclcheck() that don't work via the generic
function and have special APIs, so those stay as is.
I also changed most pg_foo_aclmask() functions to static functions,
since they are not used outside of aclchk.c.
Discussion: https://www.postgresql.org/message-id/flat/95c30f96-4060-2f48-98b5-a4392d3b6066@enterprisedb.com
---
contrib/dblink/dblink.c | 2 +-
src/backend/access/common/tupdesc.c | 2 +-
src/backend/catalog/aclchk.c | 618 ++++++-------------------
src/backend/catalog/namespace.c | 13 +-
src/backend/catalog/pg_aggregate.c | 10 +-
src/backend/catalog/pg_operator.c | 2 +-
src/backend/commands/aggregatecmds.c | 3 +-
src/backend/commands/alter.c | 6 +-
src/backend/commands/collationcmds.c | 3 +-
src/backend/commands/conversioncmds.c | 6 +-
src/backend/commands/dbcommands.c | 4 +-
src/backend/commands/extension.c | 5 +-
src/backend/commands/foreigncmds.c | 10 +-
src/backend/commands/functioncmds.c | 26 +-
src/backend/commands/indexcmds.c | 8 +-
src/backend/commands/opclasscmds.c | 4 +-
src/backend/commands/operatorcmds.c | 16 +-
src/backend/commands/publicationcmds.c | 5 +-
src/backend/commands/schemacmds.c | 7 +-
src/backend/commands/tablecmds.c | 16 +-
src/backend/commands/tablespace.c | 4 +-
src/backend/commands/trigger.c | 2 +-
src/backend/commands/tsearchcmds.c | 4 +-
src/backend/commands/typecmds.c | 16 +-
src/backend/executor/execExpr.c | 11 +-
src/backend/executor/execSRF.c | 3 +-
src/backend/executor/nodeAgg.c | 10 +-
src/backend/executor/nodeWindowAgg.c | 8 +-
src/backend/optimizer/util/clauses.c | 4 +-
src/backend/parser/parse_utilcmd.c | 2 +-
src/backend/tcop/fastpath.c | 5 +-
src/backend/utils/adt/acl.c | 102 ++--
src/backend/utils/adt/dbsize.c | 5 +-
src/backend/utils/fmgr/fmgr.c | 4 +-
src/backend/utils/init/postinit.c | 2 +-
src/include/utils/acl.h | 44 +-
src/pl/tcl/pltcl.c | 2 +-
37 files changed, 313 insertions(+), 681 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 9202c3584758..04095a8f0ee7 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -2838,7 +2838,7 @@ get_connect_string(const char *servername)
fdw = GetForeignDataWrapper(fdwid);
/* Check permissions, user must have usage on the server. */
- aclresult = pg_foreign_server_aclcheck(serverid, userid, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, userid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, foreign_server->servername);
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index b7f918c877bd..7857f55e24a4 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -821,7 +821,7 @@ BuildDescForRelation(List *schema)
attname = entry->colname;
typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
- aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, atttypid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, atttypid);
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index fac67748e6db..3a1f9c578289 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -139,8 +139,26 @@ static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
Oid objectId, Oid grantorId,
ObjectType objtype, const char *objname,
AttrNumber att_number, const char *colname);
-static AclMode pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum,
+static AclMode pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum,
Oid roleid, AclMode mask, AclMaskHow how);
+static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
+ Oid roleid, AclMode mask, AclMaskHow how);
+static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
+ Oid roleid, AclMode mask,
+ AclMaskHow how, bool *is_missing);
+static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid,
+ AclMode mask, AclMaskHow how,
+ bool *is_missing);
+static AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
+ AclMode mask, AclMaskHow how, Snapshot snapshot);
+static AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
+static AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
+ AclMode mask, AclMaskHow how);
static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid,
Acl *new_acl);
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid,
@@ -3787,47 +3805,47 @@ aclcheck_error_type(AclResult aclerr, Oid typeOid)
* Relay for the various pg_*_mask routines depending on object kind
*/
static AclMode
-pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
+pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how)
{
switch (objtype)
{
case OBJECT_COLUMN:
return
- pg_class_aclmask(table_oid, roleid, mask, how) |
- pg_attribute_aclmask(table_oid, attnum, roleid, mask, how);
+ pg_class_aclmask(object_oid, roleid, mask, how) |
+ pg_attribute_aclmask(object_oid, attnum, roleid, mask, how);
case OBJECT_TABLE:
case OBJECT_SEQUENCE:
- return pg_class_aclmask(table_oid, roleid, mask, how);
+ return pg_class_aclmask(object_oid, roleid, mask, how);
case OBJECT_DATABASE:
- return pg_database_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(DatabaseRelationId, object_oid, roleid, mask, how);
case OBJECT_FUNCTION:
- return pg_proc_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ProcedureRelationId, object_oid, roleid, mask, how);
case OBJECT_LANGUAGE:
- return pg_language_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(LanguageRelationId, object_oid, roleid, mask, how);
case OBJECT_LARGEOBJECT:
- return pg_largeobject_aclmask_snapshot(table_oid, roleid,
+ return pg_largeobject_aclmask_snapshot(object_oid, roleid,
mask, how, NULL);
case OBJECT_PARAMETER_ACL:
- return pg_parameter_acl_aclmask(table_oid, roleid, mask, how);
+ return pg_parameter_acl_aclmask(object_oid, roleid, mask, how);
case OBJECT_SCHEMA:
- return pg_namespace_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(NamespaceRelationId, object_oid, roleid, mask, how);
case OBJECT_STATISTIC_EXT:
elog(ERROR, "grantable rights not supported for statistics objects");
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
case OBJECT_TABLESPACE:
- return pg_tablespace_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(TableSpaceRelationId, object_oid, roleid, mask, how);
case OBJECT_FDW:
- return pg_foreign_data_wrapper_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ForeignDataWrapperRelationId, object_oid, roleid, mask, how);
case OBJECT_FOREIGN_SERVER:
- return pg_foreign_server_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(ForeignServerRelationId, object_oid, roleid, mask, how);
case OBJECT_EVENT_TRIGGER:
elog(ERROR, "grantable rights not supported for event triggers");
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
case OBJECT_TYPE:
- return pg_type_aclmask(table_oid, roleid, mask, how);
+ return object_aclmask(TypeRelationId, object_oid, roleid, mask, how);
default:
elog(ERROR, "unrecognized objtype: %d",
(int) objtype);
@@ -3849,14 +3867,85 @@ pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
*/
/*
- * Exported routine for examining a user's privileges for a column
+ * Generic routine for examining a user's privileges for an object
+ */
+static AclMode
+object_aclmask(Oid classid, Oid objectid, Oid roleid,
+ AclMode mask, AclMaskHow how)
+{
+ AclMode result;
+ HeapTuple tuple;
+ Datum aclDatum;
+ bool isNull;
+ Acl *acl;
+ Oid ownerId;
+
+ /* Special cases */
+ switch (classid)
+ {
+ case NamespaceRelationId:
+ return pg_namespace_aclmask(objectid, roleid, mask, how);
+ case TypeRelationId:
+ return pg_type_aclmask(objectid, roleid, mask, how);
+ }
+
+ /* Even more special cases */
+ Assert(classid != RelationRelationId); /* should use pg_class_acl* */
+ Assert(classid != LargeObjectMetadataRelationId); /* should use pg_largeobject_acl* */
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return mask;
+
+ /*
+ * Get the objects's ACL from its catalog
+ */
+ tuple = SearchSysCache1(get_object_catcache_oid(classid), ObjectIdGetDatum(objectid));
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
+
+ ownerId = DatumGetObjectId(SysCacheGetAttr(get_object_catcache_oid(classid),
+ tuple,
+ get_object_attnum_owner(classid),
+ &isNull));
+ Assert(!isNull);
+
+ aclDatum = SysCacheGetAttr(get_object_catcache_oid(classid), tuple, get_object_attnum_acl(classid),
+ &isNull);
+ if (isNull)
+ {
+ /* No ACL, so build default ACL */
+ acl = acldefault(get_object_type(classid, objectid), ownerId);
+ aclDatum = (Datum) 0;
+ }
+ else
+ {
+ /* detoast ACL if necessary */
+ acl = DatumGetAclP(aclDatum);
+ }
+
+ result = aclmask(acl, roleid, ownerId, mask, how);
+
+ /* if we have a detoasted copy, free it */
+ if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
+ pfree(acl);
+
+ ReleaseSysCache(tuple);
+
+ return result;
+}
+
+/*
+ * Routine for examining a user's privileges for a column
*
* Note: this considers only privileges granted specifically on the column.
* It is caller's responsibility to take relation-level privileges into account
* as appropriate. (For the same reason, we have no special case for
* superuser-ness here.)
*/
-AclMode
+static AclMode
pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how)
{
@@ -3865,12 +3954,12 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a column
+ * Routine for examining a user's privileges for a column
*
* Does the bulk of the work for pg_attribute_aclmask(), and allows other
* callers to avoid the missing attribute ERROR when is_missing is non-NULL.
*/
-AclMode
+static AclMode
pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how, bool *is_missing)
{
@@ -3983,12 +4072,12 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a table
+ * Routine for examining a user's privileges for a table
*
* Does the bulk of the work for pg_class_aclmask(), and allows other
* callers to avoid the missing relation ERROR when is_missing is non-NULL.
*/
-AclMode
+static AclMode
pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
AclMaskHow how, bool *is_missing)
{
@@ -4104,64 +4193,10 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
}
/*
- * Exported routine for examining a user's privileges for a database
- */
-AclMode
-pg_database_aclmask(Oid db_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the database's ACL from pg_database
- */
- 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)));
-
- ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
-
- aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_DATABASE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a configuration
+ * Routine for examining a user's privileges for a configuration
* parameter (GUC), identified by GUC name.
*/
-AclMode
+static AclMode
pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4222,10 +4257,10 @@ pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
}
/*
- * Exported routine for examining a user's privileges for a configuration
+ * Routine for examining a user's privileges for a configuration
* parameter (GUC), identified by the OID of its pg_parameter_acl entry.
*/
-AclMode
+static AclMode
pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4273,115 +4308,7 @@ pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
}
/*
- * Exported routine for examining a user's privileges for a function
- */
-AclMode
-pg_proc_aclmask(Oid proc_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the function's ACL from pg_proc
- */
- 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;
-
- aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FUNCTION, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a language
- */
-AclMode
-pg_language_aclmask(Oid lang_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the language's ACL from pg_language
- */
- tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language with OID %u does not exist", lang_oid)));
-
- ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
-
- aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
- &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_LANGUAGE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a largeobject
+ * Routine for examining a user's privileges for a largeobject
*
* When a large object is opened for reading, it is opened relative to the
* caller's snapshot, but when it is opened for writing, a current
@@ -4392,7 +4319,7 @@ pg_language_aclmask(Oid lang_oid, Oid roleid,
* snapshot, since all we do with the snapshot argument is pass it through
* to systable_beginscan().
*/
-AclMode
+static AclMode
pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
AclMode mask, AclMaskHow how,
Snapshot snapshot)
@@ -4463,9 +4390,9 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a namespace
+ * Routine for examining a user's privileges for a namespace
*/
-AclMode
+static AclMode
pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
@@ -4501,7 +4428,7 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
*/
if (isTempNamespace(nsp_oid))
{
- if (pg_database_aclcheck(MyDatabaseId, roleid,
+ if (object_aclcheck(DatabaseRelationId, MyDatabaseId, roleid,
ACL_CREATE_TEMP) == ACLCHECK_OK)
return mask & ACL_ALL_RIGHTS_SCHEMA;
else
@@ -4555,189 +4482,9 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
}
/*
- * Exported routine for examining a user's privileges for a tablespace
- */
-AclMode
-pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- /* Superusers bypass all permission checking. */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Get the tablespace's ACL from pg_tablespace
- */
- tuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace with OID %u does not exist", spc_oid)));
-
- ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
-
- aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple,
- Anum_pg_tablespace_spcacl,
- &isNull);
-
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_TABLESPACE, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a foreign
- * data wrapper
- */
-AclMode
-pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- Form_pg_foreign_data_wrapper fdwForm;
-
- /* Bypass permission checks for superusers */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Must get the FDW's tuple from pg_foreign_data_wrapper
- */
- tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdw_oid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("foreign-data wrapper with OID %u does not exist",
- fdw_oid)));
- fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
-
- /*
- * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
- */
- ownerId = fdwForm->fdwowner;
-
- aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
- Anum_pg_foreign_data_wrapper_fdwacl, &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FDW, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast rel's ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a foreign
- * server.
- */
-AclMode
-pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
- AclMode mask, AclMaskHow how)
-{
- AclMode result;
- HeapTuple tuple;
- Datum aclDatum;
- bool isNull;
- Acl *acl;
- Oid ownerId;
-
- Form_pg_foreign_server srvForm;
-
- /* Bypass permission checks for superusers */
- if (superuser_arg(roleid))
- return mask;
-
- /*
- * Must get the FDW's tuple from pg_foreign_data_wrapper
- */
- 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)));
- srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
-
- /*
- * Normal case: get the foreign server's ACL from pg_foreign_server
- */
- ownerId = srvForm->srvowner;
-
- aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
- Anum_pg_foreign_server_srvacl, &isNull);
- if (isNull)
- {
- /* No ACL, so build default ACL */
- acl = acldefault(OBJECT_FOREIGN_SERVER, ownerId);
- aclDatum = (Datum) 0;
- }
- else
- {
- /* detoast rel's ACL if necessary */
- acl = DatumGetAclP(aclDatum);
- }
-
- result = aclmask(acl, roleid, ownerId, mask, how);
-
- /* if we have a detoasted copy, free it */
- if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
- pfree(acl);
-
- ReleaseSysCache(tuple);
-
- return result;
-}
-
-/*
- * Exported routine for examining a user's privileges for a type.
+ * Routine for examining a user's privileges for a type.
*/
-AclMode
+static AclMode
pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -4811,6 +4558,18 @@ pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
return result;
}
+/*
+ * Exported generic routine for checking a user's access privileges to an object
+ */
+AclResult
+object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
+{
+ if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
+ return ACLCHECK_OK;
+ else
+ return ACLCHECK_NO_PRIV;
+}
+
/*
* Exported routine for checking a user's access privileges to a column
*
@@ -4973,18 +4732,6 @@ pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a database
- */
-AclResult
-pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
-{
- if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Exported routine for checking a user's access privileges to a configuration
* parameter (GUC), identified by GUC name.
@@ -4998,43 +4745,6 @@ pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a configuration
- * parameter (GUC), identified by the OID of its pg_parameter_acl entry.
- */
-AclResult
-pg_parameter_acl_aclcheck(Oid acl_oid, Oid roleid, AclMode mode)
-{
- if (pg_parameter_acl_aclmask(acl_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a function
- */
-AclResult
-pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
-{
- if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a language
- */
-AclResult
-pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
-{
- if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Exported routine for checking a user's access privileges to a largeobject
*/
@@ -5049,68 +4759,6 @@ pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, AclMode mode,
return ACLCHECK_NO_PRIV;
}
-/*
- * Exported routine for checking a user's access privileges to a namespace
- */
-AclResult
-pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
-{
- if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a tablespace
- */
-AclResult
-pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
-{
- if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a foreign
- * data wrapper
- */
-AclResult
-pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode)
-{
- if (pg_foreign_data_wrapper_aclmask(fdw_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a foreign
- * server
- */
-AclResult
-pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode)
-{
- if (pg_foreign_server_aclmask(srv_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
-/*
- * Exported routine for checking a user's access privileges to a type
- */
-AclResult
-pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
-{
- if (pg_type_aclmask(type_oid, roleid, mode, ACLMASK_ANY) != 0)
- return ACLCHECK_OK;
- else
- return ACLCHECK_NO_PRIV;
-}
-
/*
* Generic ownership check for an object
*/
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 1543f2abcd8d..bac0deb6da3e 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -28,6 +28,7 @@
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
@@ -586,7 +587,7 @@ RangeVarGetAndCheckCreationNamespace(RangeVar *relation,
break;
/* Check namespace permissions. */
- aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, nspid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(nspid));
@@ -2954,7 +2955,7 @@ LookupExplicitNamespace(const char *nspname, bool missing_ok)
if (missing_ok && !OidIsValid(namespaceId))
return InvalidOid;
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
nspname);
@@ -2990,7 +2991,7 @@ LookupCreationNamespace(const char *nspname)
namespaceId = get_namespace_oid(nspname, false);
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
nspname);
@@ -3836,7 +3837,7 @@ recomputeNamespacePath(void)
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, roleid,
+ object_aclcheck(NamespaceRelationId, namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK &&
InvokeNamespaceSearchHook(namespaceId, false))
oidlist = lappend_oid(oidlist, namespaceId);
@@ -3864,7 +3865,7 @@ recomputeNamespacePath(void)
namespaceId = get_namespace_oid(curname, true);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, roleid,
+ object_aclcheck(NamespaceRelationId, namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK &&
InvokeNamespaceSearchHook(namespaceId, false))
oidlist = lappend_oid(oidlist, namespaceId);
@@ -4000,7 +4001,7 @@ InitTempTableNamespace(void)
* But there's no need to make the namespace in the first place until a
* temp table creation request is made by someone with appropriate rights.
*/
- if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
+ if (object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
ACL_CREATE_TEMP) != ACLCHECK_OK)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 0d0daa69b340..a98445b741a1 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -586,23 +586,23 @@ AggregateCreate(const char *aggName,
*/
for (i = 0; i < numArgs; i++)
{
- aclresult = pg_type_aclcheck(aggArgTypes[i], GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, aggArgTypes[i], GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggArgTypes[i]);
}
- aclresult = pg_type_aclcheck(aggTransType, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, aggTransType, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggTransType);
if (OidIsValid(aggmTransType))
{
- aclresult = pg_type_aclcheck(aggmTransType, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, aggmTransType, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggmTransType);
}
- aclresult = pg_type_aclcheck(finaltype, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, finaltype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, finaltype);
@@ -906,7 +906,7 @@ lookup_agg_function(List *fnName,
}
/* Check aggregate creator has permission to call the function */
- aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, fnOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(fnOid));
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index e6e794b6ff90..1017f2eed18a 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -624,7 +624,7 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
/* not in catalogs, different from operator, so make shell */
- aclresult = pg_namespace_aclcheck(otherNamespace, GetUserId(),
+ aclresult = object_aclcheck(NamespaceRelationId, otherNamespace, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 010eca7340a2..a9339e40b311 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -25,6 +25,7 @@
#include "access/htup_details.h"
#include "catalog/dependency.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/alter.h"
@@ -104,7 +105,7 @@ DefineAggregate(ParseState *pstate,
aggNamespace = QualifiedNameGetCreationNamespace(name, &aggName);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(aggNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, aggNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(aggNamespace));
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 55219bb0974a..fe1dce8e5928 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -228,7 +228,7 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
/* User must have CREATE privilege on the namespace */
if (OidIsValid(namespaceId))
{
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -757,7 +757,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
NameStr(*(DatumGetName(name))));
/* User must have CREATE privilege on new namespace */
- aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(nspOid));
@@ -1006,7 +1006,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
{
AclResult aclresult;
- aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId,
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 1753d67b612c..25efa6e0bf0c 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -23,6 +23,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "commands/alter.h"
#include "commands/collationcmds.h"
#include "commands/comment.h"
@@ -76,7 +77,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collNamespace = QualifiedNameGetCreationNamespace(names, &collName);
- aclresult = pg_namespace_aclcheck(collNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, collNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(collNamespace));
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 67feda33ec59..7f721cca7142 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -18,6 +18,8 @@
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_conversion.h"
+#include "catalog/pg_namespace.h"
+#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/alter.h"
#include "commands/conversioncmds.h"
@@ -54,7 +56,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
&conversion_name);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceId));
@@ -101,7 +103,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
NameListToString(func_name), "integer")));
/* Check we have EXECUTE rights for the function */
- aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, funcoid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(func_name));
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 0d6a1228639d..a67ea86619c8 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -1164,7 +1164,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
tablespacename = defGetString(dtablespacename);
dst_deftablespace = get_tablespace_oid(tablespacename, false);
/* check permissions */
- aclresult = pg_tablespace_aclcheck(dst_deftablespace, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, dst_deftablespace, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
@@ -1874,7 +1874,7 @@ movedb(const char *dbname, const char *tblspcname)
/*
* Permission checks
*/
- aclresult = pg_tablespace_aclcheck(dst_tblspcoid, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, dst_tblspcoid, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 722e94bbce04..806d6056ab6f 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -42,6 +42,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_namespace.h"
@@ -832,7 +833,7 @@ extension_is_trusted(ExtensionControlFile *control)
if (!control->trusted)
return false;
/* Allow if user has CREATE privilege on current database */
- aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
if (aclresult == ACLCHECK_OK)
return true;
return false;
@@ -2732,7 +2733,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o
extensionName);
/* Permission check: must have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA, newschema);
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index e6e6d128d11a..55b0be9e1d11 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -366,7 +366,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have USAGE privilege on foreign-data wrapper */
- aclresult = pg_foreign_data_wrapper_aclcheck(form->srvfdw, newOwnerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
{
ForeignDataWrapper *fdw = GetForeignDataWrapper(form->srvfdw);
@@ -891,7 +891,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
*/
fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdw->fdwid, ownerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdw->fdwid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FDW, fdw->fdwname);
@@ -1082,7 +1082,7 @@ user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
{
AclResult aclresult;
- aclresult = pg_foreign_server_aclcheck(serverid, curuserid, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, curuserid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, servername);
}
@@ -1433,7 +1433,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
* get the actual FDW for option validation etc.
*/
server = GetForeignServerByName(stmt->servername, false);
- aclresult = pg_foreign_server_aclcheck(server->serverid, ownerId, ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
@@ -1492,7 +1492,7 @@ ImportForeignSchema(ImportForeignSchemaStmt *stmt)
/* Check that the foreign server exists and that we have USAGE on it */
server = GetForeignServerByName(stmt->server_name, false);
- aclresult = pg_foreign_server_aclcheck(server->serverid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3645216c4b59..57489f65f2e7 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -150,7 +150,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
errdetail("Creating a shell type definition.")));
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
&typname);
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -160,7 +160,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
Assert(OidIsValid(rettype));
}
- aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, rettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, rettype);
@@ -272,7 +272,7 @@ interpret_function_parameter_list(ParseState *pstate,
toid = InvalidOid; /* keep compiler quiet */
}
- aclresult = pg_type_aclcheck(toid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, toid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, toid);
@@ -1057,7 +1057,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
&funcname);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceId));
@@ -1111,7 +1111,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
if (languageStruct->lanpltrusted)
{
/* if trusted language, need USAGE privilege */
- aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(LanguageRelationId, languageOid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
NameStr(languageStruct->lanname));
@@ -1562,11 +1562,11 @@ CreateCast(CreateCastStmt *stmt)
format_type_be(sourcetypeid),
format_type_be(targettypeid))));
- aclresult = pg_type_aclcheck(sourcetypeid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, sourcetypeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, sourcetypeid);
- aclresult = pg_type_aclcheck(targettypeid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, targettypeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, targettypeid);
@@ -1841,7 +1841,7 @@ CreateTransform(CreateTransformStmt *stmt)
if (!object_ownercheck(TypeRelationId, typeid, GetUserId()))
aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid);
- aclresult = pg_type_aclcheck(typeid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, typeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeid);
@@ -1850,7 +1850,7 @@ CreateTransform(CreateTransformStmt *stmt)
*/
langid = get_language_oid(stmt->lang, false);
- aclresult = pg_language_aclcheck(langid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(LanguageRelationId, langid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE, stmt->lang);
@@ -1864,7 +1864,7 @@ CreateTransform(CreateTransformStmt *stmt)
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);
+ aclresult = object_aclcheck(ProcedureRelationId, fromsqlfuncid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, NameListToString(stmt->fromsql->objname));
@@ -1890,7 +1890,7 @@ CreateTransform(CreateTransformStmt *stmt)
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);
+ aclresult = object_aclcheck(ProcedureRelationId, tosqlfuncid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, NameListToString(stmt->tosql->objname));
@@ -2116,7 +2116,7 @@ ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic)
/* if trusted language, need USAGE privilege */
AclResult aclresult;
- aclresult = pg_language_aclcheck(codeblock->langOid, GetUserId(),
+ aclresult = object_aclcheck(LanguageRelationId, codeblock->langOid, GetUserId(),
ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
@@ -2193,7 +2193,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
Assert(fexpr);
Assert(IsA(fexpr, FuncExpr));
- aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, fexpr->funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_PROCEDURE, get_func_name(fexpr->funcid));
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index aadd67b07f5a..91cee27743da 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -742,7 +742,7 @@ DefineIndex(Oid relationId,
{
AclResult aclresult;
- aclresult = pg_namespace_aclcheck(namespaceId, root_save_userid,
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceId, root_save_userid,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -774,7 +774,7 @@ DefineIndex(Oid relationId,
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(tablespaceId, root_save_userid,
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, root_save_userid,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
@@ -2648,7 +2648,7 @@ ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel)
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(params.tablespaceOid,
+ aclresult = object_aclcheck(TableSpaceRelationId, params.tablespaceOid,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
@@ -3245,7 +3245,7 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(params->tablespaceOid,
+ aclresult = object_aclcheck(TableSpaceRelationId, params->tablespaceOid,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index c004e303e282..0bc6deda0084 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -362,7 +362,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
&opcname);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceoid));
@@ -781,7 +781,7 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
&opfname);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceoid));
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index a2d7ae89d741..8dc57976268a 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -36,7 +36,9 @@
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h"
+#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/alter.h"
#include "commands/defrem.h"
@@ -90,7 +92,7 @@ DefineOperator(List *names, List *parameters)
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, oprNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(oprNamespace));
@@ -187,14 +189,14 @@ DefineOperator(List *names, List *parameters)
if (typeName1)
{
- aclresult = pg_type_aclcheck(typeId1, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, typeId1, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeId1);
}
if (typeName2)
{
- aclresult = pg_type_aclcheck(typeId2, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, typeId2, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeId2);
}
@@ -225,13 +227,13 @@ DefineOperator(List *names, List *parameters)
* necessary, since EXECUTE will be checked at any attempted use of the
* operator, but it seems like a good idea anyway.
*/
- aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, functionOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(functionName));
rettype = get_func_rettype(functionOid);
- aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, rettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, rettype);
@@ -291,7 +293,7 @@ ValidateRestrictionEstimator(List *restrictionName)
NameListToString(restrictionName), "float8")));
/* Require EXECUTE rights for the estimator */
- aclresult = pg_proc_aclcheck(restrictionOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, restrictionOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(restrictionName));
@@ -349,7 +351,7 @@ ValidateJoinEstimator(List *joinName)
NameListToString(joinName), "float8")));
/* Require EXECUTE rights for the estimator */
- aclresult = pg_proc_aclcheck(joinOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, joinOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(joinName));
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 8428e9e7b220..940655b9be04 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -24,6 +24,7 @@
#include "catalog/objectaccess.h"
#include "catalog/objectaddress.h"
#include "catalog/partition.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
@@ -748,7 +749,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
List *schemaidlist = NIL;
/* must have CREATE privilege on database */
- aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_DATABASE,
get_database_name(MyDatabaseId));
@@ -1913,7 +1914,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on database */
- aclresult = pg_database_aclcheck(MyDatabaseId, newOwnerId, ACL_CREATE);
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, newOwnerId, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_DATABASE,
get_database_name(MyDatabaseId));
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 3005a059e823..b03f07a23222 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -23,6 +23,7 @@
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
#include "commands/event_trigger.h"
@@ -91,7 +92,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
* The latter provision guards against "giveaway" attacks. Note that a
* superuser will always have both of these privileges a fortiori.
*/
- aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, saved_uid, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_DATABASE,
get_database_name(MyDatabaseId));
@@ -259,7 +260,7 @@ RenameSchema(const char *oldname, const char *newname)
oldname);
/* must have CREATE privilege on database */
- aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_DATABASE,
get_database_name(MyDatabaseId));
@@ -380,7 +381,7 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
* schemas. Because superusers will always have this right, we need
* no special case for them.
*/
- aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(),
+ aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_DATABASE,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c6d518012d25..bb5773c61b34 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -804,7 +804,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
@@ -845,7 +845,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
- aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, ofTypeId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, ofTypeId);
}
@@ -6830,7 +6830,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = tform->oid;
- aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, typeOid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeOid);
@@ -12164,7 +12164,7 @@ ATPrepAlterColumnType(List **wqueue,
/* Look up the target type */
typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
- aclresult = pg_type_aclcheck(targettype, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, targettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, targettype);
@@ -13836,7 +13836,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceOid, newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -14152,7 +14152,7 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, const char *tablespacen
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE, tablespacename);
}
@@ -14545,7 +14545,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
{
AclResult aclresult;
- aclresult = pg_tablespace_aclcheck(new_tablespaceoid, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, new_tablespaceoid, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
@@ -17052,7 +17052,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
*/
if (IsA(stmt, RenameStmt))
{
- aclresult = pg_namespace_aclcheck(classform->relnamespace,
+ aclresult = object_aclcheck(NamespaceRelationId, classform->relnamespace,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index b60cb712c1f6..76e100b56024 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -1277,7 +1277,7 @@ check_temp_tablespaces(char **newval, void **extra, GucSource source)
}
/* Check permissions, similarly complaining only if interactive */
- aclresult = pg_tablespace_aclcheck(curoid, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, curoid, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
{
@@ -1407,7 +1407,7 @@ PrepareTempTablespaces(void)
}
/* Check permissions similarly */
- aclresult = pg_tablespace_aclcheck(curoid, GetUserId(),
+ aclresult = object_aclcheck(TableSpaceRelationId, curoid, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
continue;
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index df408092820c..aaf54874be2c 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -696,7 +696,7 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString,
funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
if (!isInternal)
{
- aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, funcoid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(stmt->funcname));
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 365bfd30fdfe..9304c53d4bae 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -408,7 +408,7 @@ DefineTSDictionary(List *names, List *parameters)
namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceoid));
@@ -911,7 +911,7 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceoid));
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index b7e0194d2367..ecc8b3f44c90 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -222,7 +222,7 @@ DefineType(ParseState *pstate, List *names, List *parameters)
#ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(typeNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, typeNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(typeNamespace));
@@ -733,7 +733,7 @@ DefineDomain(CreateDomainStmt *stmt)
&domainName);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(domainNamespace, GetUserId(),
+ aclresult = object_aclcheck(NamespaceRelationId, domainNamespace, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -781,7 +781,7 @@ DefineDomain(CreateDomainStmt *stmt)
errmsg("\"%s\" is not a valid base type for a domain",
TypeNameToString(stmt->typeName))));
- aclresult = pg_type_aclcheck(basetypeoid, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(TypeRelationId, basetypeoid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, basetypeoid);
@@ -1149,7 +1149,7 @@ DefineEnum(CreateEnumStmt *stmt)
&enumName);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(enumNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, enumNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(enumNamespace));
@@ -1369,7 +1369,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
&typeName);
/* Check we have creation rights in target namespace */
- aclresult = pg_namespace_aclcheck(typeNamespace, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(NamespaceRelationId, typeNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(typeNamespace));
@@ -2341,7 +2341,7 @@ findRangeCanonicalFunction(List *procname, Oid typeOid)
func_signature_string(procname, 1, NIL, argList))));
/* Also, range type's creator must have permission to call function */
- aclresult = pg_proc_aclcheck(procOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, procOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(procOid));
@@ -2384,7 +2384,7 @@ findRangeSubtypeDiffFunction(List *procname, Oid subtype)
func_signature_string(procname, 2, NIL, argList))));
/* Also, range type's creator must have permission to call function */
- aclresult = pg_proc_aclcheck(procOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, procOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(procOid));
@@ -3748,7 +3748,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(typTup->typnamespace,
+ aclresult = object_aclcheck(NamespaceRelationId, typTup->typnamespace,
newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 25a94bbaaaa4..0ecb2f86100c 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -32,6 +32,7 @@
#include "access/nbtree.h"
#include "catalog/objectaccess.h"
+#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "executor/execExpr.h"
#include "executor/nodeSubplan.h"
@@ -1224,7 +1225,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
arrayarg = (Expr *) lsecond(opexpr->args);
/* Check permission to call function */
- aclresult = pg_proc_aclcheck(cmpfuncid,
+ aclresult = object_aclcheck(ProcedureRelationId, cmpfuncid,
GetUserId(),
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
@@ -1234,7 +1235,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
if (OidIsValid(opexpr->hashfuncid))
{
- aclresult = pg_proc_aclcheck(opexpr->hashfuncid,
+ aclresult = object_aclcheck(ProcedureRelationId, opexpr->hashfuncid,
GetUserId(),
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
@@ -2462,7 +2463,7 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
ListCell *lc;
/* Check permission to call function */
- aclresult = pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(funcid));
InvokeFunctionExecuteHook(funcid);
@@ -3797,7 +3798,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
AclResult aclresult;
/* Check permission to call function */
- aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, foid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
@@ -3931,7 +3932,7 @@ ExecBuildParamSetEqual(TupleDesc desc,
AclResult aclresult;
/* Check permission to call function */
- aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, foid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index c2ad4d731b85..d8a5e3ce35b5 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -20,6 +20,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
+#include "catalog/pg_proc.h"
#include "executor/execdebug.h"
#include "funcapi.h"
#include "miscadmin.h"
@@ -701,7 +702,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
size_t numargs = list_length(sexpr->args);
/* Check permission to call function */
- aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, foid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
InvokeFunctionExecuteHook(foid);
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 28f6f9c5c5aa..30c914318381 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -3676,7 +3676,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
/* Check permission to call aggregate function */
- aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
+ aclresult = object_aclcheck(ProcedureRelationId, aggref->aggfnoid, GetUserId(),
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_AGGREGATE,
@@ -3743,7 +3743,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
if (OidIsValid(finalfn_oid))
{
- aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, finalfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -3752,7 +3752,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
}
if (OidIsValid(serialfn_oid))
{
- aclresult = pg_proc_aclcheck(serialfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, serialfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -3761,7 +3761,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
}
if (OidIsValid(deserialfn_oid))
{
- aclresult = pg_proc_aclcheck(deserialfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, deserialfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -3841,7 +3841,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
else
transfn_oid = aggform->aggtransfn;
- aclresult = pg_proc_aclcheck(transfn_oid, aggOwner, ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, transfn_oid, aggOwner, ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
get_func_name(transfn_oid));
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 1750121c4926..81ba024bbaf2 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -2553,7 +2553,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
wfuncstate->wfuncno = wfuncno;
/* Check permission to call window function */
- aclresult = pg_proc_aclcheck(wfunc->winfnoid, GetUserId(),
+ aclresult = object_aclcheck(ProcedureRelationId, wfunc->winfnoid, GetUserId(),
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -2834,7 +2834,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner;
ReleaseSysCache(procTuple);
- aclresult = pg_proc_aclcheck(transfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, transfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -2843,7 +2843,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
if (OidIsValid(invtransfn_oid))
{
- aclresult = pg_proc_aclcheck(invtransfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, invtransfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
@@ -2853,7 +2853,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
if (OidIsValid(finalfn_oid))
{
- aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
+ aclresult = object_aclcheck(ProcedureRelationId, finalfn_oid, aggOwner,
ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 5e791333cbd6..317c10c2b9ff 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4436,7 +4436,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
return NULL;
/* Check permission to call function (fail later, if not) */
- if (pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
+ if (object_aclcheck(ProcedureRelationId, funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
return NULL;
/* Check whether a plugin wants to hook function entry/exit */
@@ -4978,7 +4978,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
return NULL;
/* Check permission to call function (fail later, if not) */
- if (pg_proc_aclcheck(func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
+ if (object_aclcheck(ProcedureRelationId, func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
return NULL;
/* Check whether a plugin wants to hook function entry/exit */
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 8140e79d8f13..487eb2041bea 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -996,7 +996,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
*/
if (relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
{
- aclresult = pg_type_aclcheck(relation->rd_rel->reltype, GetUserId(),
+ aclresult = object_aclcheck(TypeRelationId, relation->rd_rel->reltype, GetUserId(),
ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TYPE,
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index d429aa466316..4e6cc0667d35 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -20,6 +20,7 @@
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/objectaccess.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
@@ -239,13 +240,13 @@ HandleFunctionRequest(StringInfo msgBuf)
* Check permission to access and call function. Since we didn't go
* through a normal name lookup, we need to check schema usage too.
*/
- aclresult = pg_namespace_aclcheck(fip->namespace, GetUserId(), ACL_USAGE);
+ aclresult = object_aclcheck(NamespaceRelationId, fip->namespace, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(fip->namespace));
InvokeNamespaceSearchHook(fip->namespace, true);
- aclresult = pg_proc_aclcheck(fid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, fid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
get_func_name(fid));
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 4fac402e5b64..d4944d910868 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -23,7 +23,13 @@
#include "catalog/pg_authid.h"
#include "catalog/pg_class.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_foreign_data_wrapper.h"
+#include "catalog/pg_foreign_server.h"
+#include "catalog/pg_language.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_parameter_acl.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/proclang.h"
@@ -2902,7 +2908,7 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS)
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2927,7 +2933,7 @@ has_database_privilege_name(PG_FUNCTION_ARGS)
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2953,7 +2959,7 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
PG_RETURN_NULL();
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2979,7 +2985,7 @@ has_database_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
PG_RETURN_NULL();
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3002,7 +3008,7 @@ has_database_privilege_id_name(PG_FUNCTION_ARGS)
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3026,7 +3032,7 @@ has_database_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
PG_RETURN_NULL();
- aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
+ aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3099,7 +3105,7 @@ has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3124,7 +3130,7 @@ has_foreign_data_wrapper_privilege_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3150,7 +3156,7 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3176,7 +3182,7 @@ has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3199,7 +3205,7 @@ has_foreign_data_wrapper_privilege_id_name(PG_FUNCTION_ARGS)
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3223,7 +3229,7 @@ has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
+ aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3290,7 +3296,7 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS)
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3315,7 +3321,7 @@ has_function_privilege_name(PG_FUNCTION_ARGS)
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3341,7 +3347,7 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
PG_RETURN_NULL();
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3367,7 +3373,7 @@ has_function_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
PG_RETURN_NULL();
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3390,7 +3396,7 @@ has_function_privilege_id_name(PG_FUNCTION_ARGS)
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3414,7 +3420,7 @@ has_function_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
PG_RETURN_NULL();
- aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
+ aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3490,7 +3496,7 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3515,7 +3521,7 @@ has_language_privilege_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3541,7 +3547,7 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3567,7 +3573,7 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3590,7 +3596,7 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3614,7 +3620,7 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
PG_RETURN_NULL();
- aclresult = pg_language_aclcheck(languageoid, roleid, mode);
+ aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3681,7 +3687,7 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS)
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3706,7 +3712,7 @@ has_schema_privilege_name(PG_FUNCTION_ARGS)
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3732,7 +3738,7 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
PG_RETURN_NULL();
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3758,7 +3764,7 @@ has_schema_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
PG_RETURN_NULL();
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3781,7 +3787,7 @@ has_schema_privilege_id_name(PG_FUNCTION_ARGS)
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3805,7 +3811,7 @@ has_schema_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
PG_RETURN_NULL();
- aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
+ aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3874,7 +3880,7 @@ has_server_privilege_name_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3899,7 +3905,7 @@ has_server_privilege_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3925,7 +3931,7 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3951,7 +3957,7 @@ has_server_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3974,7 +3980,7 @@ has_server_privilege_id_name(PG_FUNCTION_ARGS)
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -3998,7 +4004,7 @@ has_server_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
PG_RETURN_NULL();
- aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
+ aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4065,7 +4071,7 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4090,7 +4096,7 @@ has_tablespace_privilege_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4116,7 +4122,7 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4142,7 +4148,7 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4165,7 +4171,7 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4189,7 +4195,7 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
PG_RETURN_NULL();
- aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
+ aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4255,7 +4261,7 @@ has_type_privilege_name_name(PG_FUNCTION_ARGS)
typeoid = convert_type_name(typename);
mode = convert_type_priv_string(priv_type_text);
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4280,7 +4286,7 @@ has_type_privilege_name(PG_FUNCTION_ARGS)
typeoid = convert_type_name(typename);
mode = convert_type_priv_string(priv_type_text);
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4306,7 +4312,7 @@ has_type_privilege_name_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
PG_RETURN_NULL();
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4332,7 +4338,7 @@ has_type_privilege_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
PG_RETURN_NULL();
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4355,7 +4361,7 @@ has_type_privilege_id_name(PG_FUNCTION_ARGS)
typeoid = convert_type_name(typename);
mode = convert_type_priv_string(priv_type_text);
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -4379,7 +4385,7 @@ has_type_privilege_id_id(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
PG_RETURN_NULL();
- aclresult = pg_type_aclcheck(typeoid, roleid, mode);
+ aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 0a9b93f26345..141db7c9c1c7 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -18,6 +18,7 @@
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
#include "commands/tablespace.h"
@@ -115,7 +116,7 @@ calculate_database_size(Oid dbOid)
* User must have connect privilege for target database or have privileges
* of pg_read_all_stats
*/
- aclresult = pg_database_aclcheck(dbOid, GetUserId(), ACL_CONNECT);
+ aclresult = object_aclcheck(DatabaseRelationId, dbOid, GetUserId(), ACL_CONNECT);
if (aclresult != ACLCHECK_OK &&
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
{
@@ -203,7 +204,7 @@ calculate_tablespace_size(Oid tblspcOid)
if (tblspcOid != MyDatabaseTableSpace &&
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
{
- aclresult = pg_tablespace_aclcheck(tblspcOid, GetUserId(), ACL_CREATE);
+ aclresult = object_aclcheck(TableSpaceRelationId, tblspcOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
get_tablespace_name(tblspcOid));
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index a9dd068095bf..3c210297aa12 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -2054,7 +2054,7 @@ CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
langStruct->lanvalidator)));
/* first validate that we have permissions to use the language */
- aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
+ aclresult = object_aclcheck(LanguageRelationId, procStruct->prolang, GetUserId(),
ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
@@ -2065,7 +2065,7 @@ CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
* execute it, there should be no possible side-effect of
* compiling/validation that execution can't have.
*/
- aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, functionOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 31b7e1de5df8..a990c833c5b4 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -359,7 +359,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
* and save a few cycles.)
*/
if (!am_superuser &&
- pg_database_aclcheck(MyDatabaseId, GetUserId(),
+ object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
ACL_CONNECT) != ACLCHECK_OK)
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 79eff5976890..35b3d8dd88be 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -235,39 +235,13 @@ extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivi
extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
-extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
- Oid roleid, AclMode mask, AclMaskHow how);
-extern AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
- Oid roleid, AclMode mask,
- AclMaskHow how, bool *is_missing);
extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid,
- AclMode mask, AclMaskHow how,
- bool *is_missing);
-extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_parameter_aclmask(const char *name, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
- AclMode mask, AclMaskHow how, Snapshot snapshot);
-extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
-extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
- AclMode mask, AclMaskHow how);
+/* generic function */
+extern AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode);
+
+/* special cases */
extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
Oid roleid, AclMode mode);
extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
@@ -278,20 +252,10 @@ extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
AclMode mode, bool *is_missing);
-extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
extern AclResult pg_parameter_aclcheck(const char *name, Oid roleid,
AclMode mode);
-extern AclResult pg_parameter_acl_aclcheck(Oid acl_oid, Oid roleid,
- AclMode mode);
-extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
-extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
extern AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid,
AclMode mode, Snapshot snapshot);
-extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
-extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
-extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode);
-extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode);
-extern AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode);
extern void aclcheck_error(AclResult aclerr, ObjectType objtype,
const char *objectname);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index eaa98d42c2e6..4185fb122109 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -619,7 +619,7 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted)
procOid = LookupFuncName(namelist, 0, NULL, false);
/* Current user must have permission to call function */
- aclresult = pg_proc_aclcheck(procOid, GetUserId(), ACL_EXECUTE);
+ aclresult = object_aclcheck(ProcedureRelationId, procOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, start_proc);
--
2.38.1
After considering this again, I decided to brute-force this and get rid
of all the trivial wrapper functions and also several of the special
cases. That way, there is less confusion at the call sites about why
this or that style is used in a particular case. Also, it now makes
sure you can't accidentally use the generic functions when a particular
one should be used.
+1
However, the aclcheck patch isn't applying for me now. That patch modifies
37 files, so it's hard to say just which commit conflicts.
On 09.11.22 19:12, Corey Huinker wrote:
After considering this again, I decided to brute-force this and get rid
of all the trivial wrapper functions and also several of the special
cases. That way, there is less confusion at the call sites about why
this or that style is used in a particular case. Also, it now makes
sure you can't accidentally use the generic functions when a particular
one should be used.+1
committed