]> granicus.if.org Git - postgresql/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:10 +0000 (01:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 24 Feb 2009 01:39:10 +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 71e0f9d3962d039fee9f8ccffbe2dae563cac52a..ba0e25e85047cec6e2ed15cde908cfb7babd0afd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.292.2.2 2006/04/24 01:40:39 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.292.2.3 2009/02/24 01:39:10 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -70,7 +70,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);
@@ -629,13 +630,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 */
@@ -730,7 +733,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 ab250b02ea9aa77246e85f1f05693507e51b0be1..215ade7c11757f0df4d0fb1d38676fe065a1ec55 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.104 2005/10/15 02:49:14 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.104.2.1 2009/02/24 01:39:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,7 +40,7 @@
  * ----------------------------------------------------------------
  */
 Oid
-TypeShellMake(const char *typeName, Oid typeNamespace)
+TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 {
        Relation        pg_type_desc;
        TupleDesc       tupDesc;
@@ -75,7 +75,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(0);         /* typlen */
        values[i++] = BoolGetDatum(false);      /* typbyval */
        values[i++] = CharGetDatum(0);          /* typtype */
@@ -117,7 +117,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
                                                                 typoid,
                                                                 InvalidOid,
                                                                 0,
-                                                                GetUserId(),
+                                                                ownerId,
                                                                 InvalidOid,
                                                                 InvalidOid,
                                                                 InvalidOid,
@@ -150,6 +150,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,
@@ -224,7 +225,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 */
@@ -323,7 +324,7 @@ TypeCreate(const char *typeName,
                                                                 typeObjectId,
                                                                 relationOid,
                                                                 relationKind,
-                                                                GetUserId(),
+                                                                ownerId,
                                                                 inputProcedure,
                                                                 outputProcedure,
                                                                 receiveProcedure,
index f4d6164775ee48e636aa78c819b9755c1a16a96d..13e4b45915a08fabfce354d02c8c68bf71fca658 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.69 2005/10/15 02:49:15 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.69.2.1 2009/02/24 01:39:10 tgl Exp $
  *
  * DESCRIPTION
  *       These routines take the parse tree and pick out the
@@ -123,7 +123,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 dd5b52bc97a0e7c60b4a87e6966aa2383da8c9a1..93d6bc85e4108bcb707b6237d0447e24f4dfe377 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.82.2.2 2007/06/20 18:16:04 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.82.2.3 2009/02/24 01:39:10 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -251,7 +251,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();
        }
@@ -338,6 +338,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 */
@@ -370,6 +371,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 */
@@ -732,6 +734,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 ba3dc0d59790cdccf33bcd124405174a7542c675..4d2280cfea1c4ad20d6397a0f387d2911833ba89 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.166.2.1 2005/11/22 18:23:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.166.2.2 2009/02/24 01:39:10 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -550,12 +550,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,