From 79dfa24649bbbaa552f8c00679f51a8f8eadb129 Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 2 Oct 2014 23:24:01 +0300 Subject: [PATCH] Cleanup: unify checks for catalog modification --- src/backend/catalog/catalog.c | 15 ++++++++++++ src/backend/commands/policy.c | 14 ++--------- src/backend/commands/tablecmds.c | 49 ++++++------------------------------- src/backend/commands/trigger.c | 18 +++----------- src/backend/rewrite/rewriteDefine.c | 12 ++------- src/include/catalog/catalog.h | 1 + 6 files changed, 30 insertions(+), 79 deletions(-) diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 2eb2c2f..db15d8e 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -92,6 +92,21 @@ IsCatalogRelation(Relation relation) } /* + * ForbidSystemTableMods + * Emit error when referenced class is a system catalog and catalog + * modifications (allow_system_table_mods) are not allowed. + */ +void +ForbidSystemTableMods(Oid relid, Form_pg_class reltuple) +{ + if (!allowSystemTableMods && IsSystemClass(relid, reltuple)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied: \"%s\" is a system catalog", + NameStr(reltuple->relname)))); +} + +/* * IsCatalogClass * True iff the relation is a system catalog relation. * diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index 3627539..00ad109 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -76,13 +76,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid, /* Must own relation. */ if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rv->relname); - - /* No system table modifications unless explicitly allowed. */ - if (!allowSystemTableMods && IsSystemClass(relid, classform)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - rv->relname))); + ForbidSystemTableMods(relid, classform); /* Relation type MUST be a table. */ if (relkind != RELKIND_RELATION) @@ -409,11 +403,7 @@ RemovePolicyById(Oid policy_id) errmsg("\"%s\" is not a table", RelationGetRelationName(rel)))); - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + ForbidSystemTableMods(relid, rel->rd_rel); simple_heap_delete(pg_rowsecurity_rel, &tuple->t_self); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ecdff1e..1b6086d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -941,12 +941,7 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, !pg_namespace_ownercheck(classform->relnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rel->relname); - - if (!allowSystemTableMods && IsSystemClass(relOid, classform)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - rel->relname))); + ForbidSystemTableMods(relOid, classform); ReleaseSysCache(tuple); @@ -1279,12 +1274,7 @@ truncate_check_rel(Relation rel) if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); - - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + ForbidSystemTableMods(rel->rd_id, rel->rd_rel); /* * Don't allow truncate on temp tables of other backends ... their local @@ -2146,11 +2136,7 @@ renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing) if (!pg_class_ownercheck(myrelid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, NameStr(classform->relname)); - if (!allowSystemTableMods && IsSystemClass(myrelid, classform)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - NameStr(classform->relname)))); + ForbidSystemTableMods(myrelid, classform); } /* @@ -4206,12 +4192,7 @@ ATSimplePermissions(Relation rel, int allowed_targets) if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); - - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + ForbidSystemTableMods(rel->rd_id, rel->rd_rel); } /* @@ -6037,11 +6018,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, errmsg("referenced relation \"%s\" is not a table", RelationGetRelationName(pkrel)))); - if (!allowSystemTableMods && IsSystemRelation(pkrel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(pkrel)))); + ForbidSystemTableMods(pkrel->rd_id, pkrel->rd_rel); /* * References from permanent or unlogged tables to temp tables, and from @@ -11481,13 +11458,7 @@ RangeVarCallbackOwnsRelation(const RangeVar *relation, if (!pg_class_ownercheck(relId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, relation->relname); - - if (!allowSystemTableMods && - IsSystemClass(relId, (Form_pg_class) GETSTRUCT(tuple))) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - relation->relname))); + ForbidSystemTableMods(relId, (Form_pg_class) GETSTRUCT(tuple)); ReleaseSysCache(tuple); } @@ -11516,13 +11487,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid, /* Must own relation. */ if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rv->relname); - - /* No system table modifications unless explicitly allowed. */ - if (!allowSystemTableMods && IsSystemClass(relid, classform)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - rv->relname))); + ForbidSystemTableMods(relid, classform); /* * Extract the specified relation type from the statement parse tree. diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index f4c0ffa..43bdd32 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -226,11 +226,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, errmsg("\"%s\" is not a table or view", RelationGetRelationName(rel)))); - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + ForbidSystemTableMods(rel->rd_id, rel->rd_rel); if (stmt->isconstraint) { @@ -1112,11 +1108,7 @@ RemoveTriggerById(Oid trigOid) errmsg("\"%s\" is not a table, view, or foreign table", RelationGetRelationName(rel)))); - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + ForbidSystemTableMods(relid, rel->rd_rel); /* * Delete the pg_trigger tuple. @@ -1220,11 +1212,7 @@ RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid, /* you must own the table to rename one of its triggers */ if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rv->relname); - if (!allowSystemTableMods && IsSystemClass(relid, form)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - rv->relname))); + ForbidSystemTableMods(relid, form); ReleaseSysCache(tuple); } diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 660d069..8ea51d8 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -265,11 +265,7 @@ DefineQueryRewrite(char *rulename, errmsg("\"%s\" is not a table or view", RelationGetRelationName(event_relation)))); - if (!allowSystemTableMods && IsSystemRelation(event_relation)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(event_relation)))); + ForbidSystemTableMods(event_relid, event_relation->rd_rel); /* * Check user has permission to apply rules to this relation. @@ -881,11 +877,7 @@ RangeVarCallbackForRenameRule(const RangeVar *rv, Oid relid, Oid oldrelid, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table or view", rv->relname))); - if (!allowSystemTableMods && IsSystemClass(relid, form)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - rv->relname))); + ForbidSystemTableMods(relid, form); /* you must own the table to rename one of its rules */ if (!pg_class_ownercheck(relid, GetUserId())) diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 9d63ac2..553ceb2 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -34,6 +34,7 @@ extern bool IsCatalogRelation(Relation relation); extern bool IsSystemClass(Oid relid, Form_pg_class reltuple); extern bool IsToastClass(Form_pg_class reltuple); extern bool IsCatalogClass(Oid relid, Form_pg_class reltuple); +extern void ForbidSystemTableMods(Oid relid, Form_pg_class reltuple); extern bool IsSystemNamespace(Oid namespaceId); extern bool IsToastNamespace(Oid namespaceId); -- 2.1.2