In pg_upgrade, verify that the install user has the same oid on both
authorBruce Momjian
Wed, 13 Jun 2012 16:19:18 +0000 (12:19 -0400)
committerBruce Momjian
Wed, 13 Jun 2012 16:19:18 +0000 (12:19 -0400)
clusters, and make sure the new cluster has no additional users.

Backpatch to 9.1.

contrib/pg_upgrade/check.c
contrib/pg_upgrade/pg_upgrade.c
contrib/pg_upgrade/pg_upgrade.h

index eed4a1eba7c7cebf271aa9ba22728f515a65d358..71d8f7514da9fe8bd5c87c6753dad474b70acbaf 100644 (file)
@@ -121,17 +121,36 @@ check_new_cluster(void)
 {
    set_locale_and_encoding(&new_cluster);
 
+   check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
+
    get_db_and_rel_infos(&new_cluster);
 
    check_new_cluster_is_empty();
-   check_for_prepared_transactions(&new_cluster);
 
    check_loadable_libraries();
 
-   check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
-
    if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
        check_hard_link();
+
+   check_is_super_user(&new_cluster);
+
+   /*
+    *  We don't restore our own user, so both clusters must match have
+    *  matching install-user oids.
+    */
+   if (old_cluster.install_role_oid != new_cluster.install_role_oid)
+       pg_log(PG_FATAL,
+       "Old and new cluster install users have different values for pg_authid.oid.\n");
+
+   /*
+    *  We only allow the install user in the new cluster because other
+    *  defined users might match users defined in the old cluster and
+    *  generate an error during pg_dump restore.
+    */
+   if (new_cluster.role_count != 1)
+       pg_log(PG_FATAL, "Only the install user can be defined in the new cluster.\n");
+    
+   check_for_prepared_transactions(&new_cluster);
 }
 
 
@@ -580,7 +599,7 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
 /*
  * check_is_super_user()
  *
- * Make sure we are the super-user.
+ * Check we are superuser, and out user id and user count
  */
 static void
 check_is_super_user(ClusterInfo *cluster)
@@ -592,7 +611,7 @@ check_is_super_user(ClusterInfo *cluster)
 
    /* Can't use pg_authid because only superusers can view it. */
    res = executeQueryOrDie(conn,
-                           "SELECT rolsuper "
+                           "SELECT rolsuper, oid "
                            "FROM pg_catalog.pg_roles "
                            "WHERE rolname = current_user");
 
@@ -600,6 +619,19 @@ check_is_super_user(ClusterInfo *cluster)
        pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n",
               os_info.user);
 
+   cluster->install_role_oid = atooid(PQgetvalue(res, 0, 1));
+
+   PQclear(res);
+
+   res = executeQueryOrDie(conn,
+                           "SELECT COUNT(*) "
+                           "FROM pg_catalog.pg_roles ");
+
+   if (PQntuples(res) != 1)
+       pg_log(PG_FATAL, "could not determine the number of users\n");
+
+   cluster->role_count = atoi(PQgetvalue(res, 0, 0));
+
    PQclear(res);
 
    PQfinish(conn);
index 3537fc2bd05bbd9b9c7dfda6028826eb376485a9..27ff8fc85a17c22f98b139cebcce333bb2d8af99 100644 (file)
@@ -29,7 +29,7 @@
  * We control all assignments of pg_enum.oid because these oids are stored
  * in user tables as enum values.
  *
- * We control all assignments of pg_auth.oid because these oids are stored
+ * We control all assignments of pg_authid.oid because these oids are stored
  * in pg_largeobject_metadata.
  */
 
index d12590ac6ba294d4d76551b6d5f7726fbcde17ef..8b2062181fdfdf6c2fe5dbe9c53e65a4ce4c9f57 100644 (file)
@@ -232,6 +232,8 @@ typedef struct
    char        major_version_str[64];  /* string PG_VERSION of cluster */
    uint32      bin_version;    /* version returned from pg_ctl */
    Oid         pg_database_oid;    /* OID of pg_database relation */
+   Oid         install_role_oid;   /* OID of connected role */
+   Oid         role_count;         /* number of roles defined in the cluster */
    char       *tablespace_suffix;      /* directory specification */
 } ClusterInfo;