]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Repair a longstanding bug in CLUSTER and the rewriting variants of ALTER
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 24 Feb 2009 01:39:01 +0000 (01:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 24 Feb 2009 01:39:01 +0000 (01:39 +0000)
TABLE: if the command is executed by someone other than the table owner (eg,
a superuser) and the table has a toast table, the toast table's pg_type row
ends up with the wrong typowner, ie, the command issuer not the table owner.
This is quite harmless for most purposes, since no interesting permissions
checks consult the pg_type row.  However, it could lead to unexpected failures
if one later tries to drop the role that issued the command (in 8.1 or 8.2),
or strange warnings from pg_dump afterwards (in 8.3 and up, which will allow
the DROP ROLE because we don't create a "redundant" owner dependency for table
rowtypes).  Problem identified by Cott Lang.

Back-patch to 8.1.  The problem is actually far older --- the CLUSTER variant
can be demonstrated in 7.0 --- but it's mostly cosmetic before 8.1 because we
didn't track ownership dependencies before 8.1.  Also, fixing it before 8.1
would require changing the call signature of heap_create_with_catalog(), which
seems to carry a nontrivial risk of breaking add-on modules.

src/backend/catalog/heap.c
src/backend/catalog/pg_type.c
src/backend/commands/functioncmds.c
src/backend/commands/typecmds.c
src/include/catalog/pg_type.h

index d6822c73c698fc4af7c529f6e0188247e36c50c4..72a97b8b7a2d116d4e206f7822ba9faee156a5f6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.314 2006/11/05 22:42:08 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.314.2.1 2009/02/24 01:39:01 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -69,7 +69,8 @@ static void AddNewRelationTuple(Relation pg_class_desc,
 static Oid AddNewRelationType(const char *typeName,
                                   Oid typeNamespace,
                                   Oid new_rel_oid,
-                                  char new_rel_kind);
+                                  char new_rel_kind,
+                                  Oid ownerid);
 static void RelationRemoveInheritance(Oid relid);
 static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
 static void StoreConstraints(Relation rel, TupleDesc tupdesc);
@@ -710,13 +711,15 @@ static Oid
 AddNewRelationType(const char *typeName,
                                   Oid typeNamespace,
                                   Oid new_rel_oid,
-                                  char new_rel_kind)
+                                  char new_rel_kind,
+                                  Oid ownerid)
 {
        return
                TypeCreate(typeName,    /* type name */
                                   typeNamespace,               /* type namespace */
                                   new_rel_oid, /* relation oid */
                                   new_rel_kind,        /* relation kind */
+                                  ownerid,             /* owner's ID */
                                   -1,                  /* internal size (varlena) */
                                   'c',                 /* type-type (complex) */
                                   ',',                 /* default array delimiter */
@@ -812,7 +815,8 @@ heap_create_with_catalog(const char *relname,
        new_type_oid = AddNewRelationType(relname,
                                                                          relnamespace,
                                                                          relid,
-                                                                         relkind);
+                                                                         relkind,
+                                                                         ownerid);
 
        /*
         * now create an entry in pg_class for the relation.
index 32de0b90dc1f14d2808299454ee254bb4a5fe96d..a6a2d99596df0f7b1122bb28cad2816cca8fdd23 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.108 2006/10/04 00:29:50 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.108.2.1 2009/02/24 01:39:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,7 +42,7 @@
  * ----------------------------------------------------------------
  */
 Oid
-TypeShellMake(const char *typeName, Oid typeNamespace)
+TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 {
        Relation        pg_type_desc;
        TupleDesc       tupDesc;
@@ -82,7 +82,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
        namestrcpy(&name, typeName);
        values[i++] = NameGetDatum(&name);      /* typname */
        values[i++] = ObjectIdGetDatum(typeNamespace);          /* typnamespace */
-       values[i++] = ObjectIdGetDatum(GetUserId());            /* typowner */
+       values[i++] = ObjectIdGetDatum(ownerId);        /* typowner */
        values[i++] = Int16GetDatum(sizeof(int4));      /* typlen */
        values[i++] = BoolGetDatum(true);       /* typbyval */
        values[i++] = CharGetDatum('p');        /* typtype */
@@ -124,7 +124,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
                                                                 typoid,
                                                                 InvalidOid,
                                                                 0,
-                                                                GetUserId(),
+                                                                ownerId,
                                                                 F_SHELL_IN,
                                                                 F_SHELL_OUT,
                                                                 InvalidOid,
@@ -157,6 +157,7 @@ TypeCreate(const char *typeName,
                   Oid typeNamespace,
                   Oid relationOid,             /* only for 'c'atalog types */
                   char relationKind,   /* ditto */
+                  Oid ownerId,
                   int16 internalSize,
                   char typeType,
                   char typDelim,
@@ -231,7 +232,7 @@ TypeCreate(const char *typeName,
        namestrcpy(&name, typeName);
        values[i++] = NameGetDatum(&name);      /* typname */
        values[i++] = ObjectIdGetDatum(typeNamespace);          /* typnamespace */
-       values[i++] = ObjectIdGetDatum(GetUserId());            /* typowner */
+       values[i++] = ObjectIdGetDatum(ownerId);        /* typowner */
        values[i++] = Int16GetDatum(internalSize);      /* typlen */
        values[i++] = BoolGetDatum(passedByValue);      /* typbyval */
        values[i++] = CharGetDatum(typeType);           /* typtype */
@@ -298,7 +299,7 @@ TypeCreate(const char *typeName,
                /*
                 * shell type must have been created by same owner
                 */
-               if (((Form_pg_type) GETSTRUCT(tup))->typowner != GetUserId())
+               if (((Form_pg_type) GETSTRUCT(tup))->typowner != ownerId)
                        aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, typeName);
 
                /*
@@ -336,7 +337,7 @@ TypeCreate(const char *typeName,
                                                                 typeObjectId,
                                                                 relationOid,
                                                                 relationKind,
-                                                                GetUserId(),
+                                                                ownerId,
                                                                 inputProcedure,
                                                                 outputProcedure,
                                                                 receiveProcedure,
index cd7125641236b30f6e2f4f0a3ce2795ede51d14e..99832cd326e1f4d63ba7e8a7139e3d76a22b16ea 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.80 2006/10/06 17:13:58 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.80.2.1 2009/02/24 01:39:01 tgl Exp $
  *
  * DESCRIPTION
  *       These routines take the parse tree and pick out the
@@ -122,7 +122,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
                if (aclresult != ACLCHECK_OK)
                        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                                                   get_namespace_name(namespaceId));
-               rettype = TypeShellMake(typname, namespaceId);
+               rettype = TypeShellMake(typname, namespaceId, GetUserId());
                Assert(OidIsValid(rettype));
        }
 
index 2b2b45208e1edb9a00e95e36182237753a112a4a..21d8521eb01b5927d064dd8cf7771eb772a0ccee 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.97.2.2 2007/06/20 18:15:57 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.97.2.3 2009/02/24 01:39:01 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -146,7 +146,7 @@ DefineType(List *names, List *parameters)
                                                        0, 0);
        if (!OidIsValid(typoid))
        {
-               typoid = TypeShellMake(typeName, typeNamespace);
+               typoid = TypeShellMake(typeName, typeNamespace, GetUserId());
                /* Make new shell type visible for modification below */
                CommandCounterIncrement();
 
@@ -374,6 +374,7 @@ DefineType(List *names, List *parameters)
                                   typeNamespace,               /* namespace */
                                   InvalidOid,  /* relation oid (n/a here) */
                                   0,                   /* relation kind (ditto) */
+                                  GetUserId(), /* owner's ID */
                                   internalLength,              /* internal size */
                                   'b',                 /* type-type (base type) */
                                   delimiter,   /* array element delimiter */
@@ -406,6 +407,7 @@ DefineType(List *names, List *parameters)
                           typeNamespace,       /* namespace */
                           InvalidOid,          /* relation oid (n/a here) */
                           0,                           /* relation kind (ditto) */
+                          GetUserId(),         /* owner's ID */
                           -1,                          /* internal size */
                           'b',                         /* type-type (base type) */
                           DEFAULT_TYPDELIM,    /* array element delimiter */
@@ -774,6 +776,7 @@ DefineDomain(CreateDomainStmt *stmt)
                                   domainNamespace,             /* namespace */
                                   InvalidOid,  /* relation oid (n/a here) */
                                   0,                   /* relation kind (ditto) */
+                                  GetUserId(), /* owner's ID */
                                   internalLength,              /* internal size */
                                   'd',                 /* type-type (domain type) */
                                   delimiter,   /* array element delimiter */
index 5afe0c851ad5bb97253380b3513e42c0e7549796..3dca12429c46f590e0989ac845f9071297a27b10 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.172.2.1 2006/12/28 01:09:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.172.2.2 2009/02/24 01:39:01 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -552,12 +552,15 @@ DATA(insert OID = 2283 ( anyelement               PGNSP PGUID  4 t p t \054 0 0 anyelement_in
 /*
  * prototypes for functions in pg_type.c
  */
-extern Oid     TypeShellMake(const char *typeName, Oid typeNamespace);
+extern Oid     TypeShellMake(const char *typeName,
+                                                 Oid typeNamespace,
+                                                 Oid ownerId);
 
 extern Oid TypeCreate(const char *typeName,
                   Oid typeNamespace,
                   Oid relationOid,
                   char relationKind,
+                  Oid ownerId,
                   int16 internalSize,
                   char typeType,
                   char typDelim,