]> granicus.if.org Git - postgresql/commitdiff
Refactor seclabel.c to use the new check_object_ownership function.
authorRobert Haas <rhaas@postgresql.org>
Fri, 4 Mar 2011 22:26:37 +0000 (17:26 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 4 Mar 2011 22:26:37 +0000 (17:26 -0500)
This avoids duplicate (and not-quite-matching) code, and makes the logic
for SECURITY LABEL match COMMENT and ALTER EXTENSION ADD/DROP.

src/backend/commands/seclabel.c

index 27917fc6c00e7221c2648fc474831e8a52687222..050792f4a0654d3ede591576dbc4714f12e480c3 100644 (file)
 #include "utils/memutils.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
 {
        const char *provider_name;
@@ -98,52 +91,30 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
        address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
                                                                 &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)
        {
-               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:
-                       CheckAttributeSecLabel(relation);
-                       break;
-               case OBJECT_TYPE:
-                       if (!pg_type_ownercheck(address.objectId, GetUserId()))
-                               aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-                                                          format_type_be(address.objectId));
-                       break;
-               case OBJECT_AGGREGATE:
-               case OBJECT_FUNCTION:
-                       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()))
+                       /*
+                        * Allow security labels only on columns of tables, views,
+                        * composite types, and foreign tables (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_INSUFFICIENT_PRIVILEGE),
-                                                errmsg("must be owner of large object %u",
-                                                       address.objectId)));
+                                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                                errmsg("\"%s\" is not a table, view, composite type, or foreign table",
+                                                               RelationGetRelationName(relation))));
                        break;
                default:
-                       elog(ERROR, "unrecognized object type: %d",
-                                (int) stmt->objtype);
+                       break;
        }
 
        /* Provider gets control here, may throw ERROR to veto new label. */
@@ -352,31 +323,6 @@ DeleteSecurityLabel(const ObjectAddress *object)
        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
 register_label_provider(const char *provider_name, check_object_relabel_type hook)
 {