Commit efa415da authored by Robert Haas's avatar Robert Haas

Refactor seclabel.c to use the new check_object_ownership function.

This avoids duplicate (and not-quite-matching) code, and makes the logic
for SECURITY LABEL match COMMENT and ALTER EXTENSION ADD/DROP.
parent b9cff97f
...@@ -26,13 +26,6 @@ ...@@ -26,13 +26,6 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/tqual.h" #include "utils/tqual.h"
/*
* For most object types, the permissions-checking logic is simple enough
* that it makes sense to just include it in CommentObject(). However,
* attributes require a bit more checking.
*/
static void CheckAttributeSecLabel(Relation relation);
typedef struct typedef struct
{ {
const char *provider_name; const char *provider_name;
...@@ -98,52 +91,30 @@ ExecSecLabelStmt(SecLabelStmt *stmt) ...@@ -98,52 +91,30 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
&relation, ShareUpdateExclusiveLock); &relation, ShareUpdateExclusiveLock);
/* Privilege and integrity checks. */ /* Require ownership of the target object. */
check_object_ownership(GetUserId(), stmt->objtype, address,
stmt->objname, stmt->objargs, relation);
/* Perform other integrity checks as needed. */
switch (stmt->objtype) switch (stmt->objtype)
{ {
case OBJECT_SEQUENCE:
case OBJECT_TABLE:
case OBJECT_VIEW:
case OBJECT_FOREIGN_TABLE:
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(relation));
break;
case OBJECT_COLUMN: case OBJECT_COLUMN:
CheckAttributeSecLabel(relation); /*
break; * Allow security labels only on columns of tables, views,
case OBJECT_TYPE: * composite types, and foreign tables (which are the only
if (!pg_type_ownercheck(address.objectId, GetUserId())) * relkinds for which pg_dump will dump labels).
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, */
format_type_be(address.objectId)); if (relation->rd_rel->relkind != RELKIND_RELATION &&
break; relation->rd_rel->relkind != RELKIND_VIEW &&
case OBJECT_AGGREGATE: relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
case OBJECT_FUNCTION: relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
if (!pg_proc_ownercheck(address.objectId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
NameListToString(stmt->objname));
break;
case OBJECT_SCHEMA:
if (!pg_namespace_ownercheck(address.objectId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
strVal(linitial(stmt->objname)));
break;
case OBJECT_LANGUAGE:
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to comment on procedural language")));
break;
case OBJECT_LARGEOBJECT:
if (!pg_largeobject_ownercheck(address.objectId, GetUserId()))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("must be owner of large object %u", errmsg("\"%s\" is not a table, view, composite type, or foreign table",
address.objectId))); RelationGetRelationName(relation))));
break; break;
default: default:
elog(ERROR, "unrecognized object type: %d", break;
(int) stmt->objtype);
} }
/* Provider gets control here, may throw ERROR to veto new label. */ /* Provider gets control here, may throw ERROR to veto new label. */
...@@ -352,31 +323,6 @@ DeleteSecurityLabel(const ObjectAddress *object) ...@@ -352,31 +323,6 @@ DeleteSecurityLabel(const ObjectAddress *object)
heap_close(pg_seclabel, RowExclusiveLock); heap_close(pg_seclabel, RowExclusiveLock);
} }
/*
* Check whether the user is allowed to comment on an attribute of the
* specified relation.
*/
static void
CheckAttributeSecLabel(Relation relation)
{
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(relation));
/*
* Allow security labels only on columns of tables, views, and composite
* types (which are the only relkinds for which pg_dump will dump labels).
*/
if (relation->rd_rel->relkind != RELKIND_RELATION &&
relation->rd_rel->relkind != RELKIND_VIEW &&
relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a table, view, composite type, or foreign table",
RelationGetRelationName(relation))));
}
void void
register_label_provider(const char *provider_name, check_object_relabel_type hook) register_label_provider(const char *provider_name, check_object_relabel_type hook)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment