]> granicus.if.org Git - postgresql/commitdiff
In pg_upgrade, verify that the install user has the same oid on both
authorBruce Momjian <bruce@momjian.us>
Wed, 13 Jun 2012 16:19:18 +0000 (12:19 -0400)
committerBruce Momjian <bruce@momjian.us>
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 cce5ff0c79ca8fa9d6dd08b98492f7479cac91a6..6a3a5f39d95f42d9be7e075fd9daf5b5b12c4dcf 100644 (file)
@@ -118,18 +118,38 @@ 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_old_cluster_has_new_cluster_dbs();
 
        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);
 }
 
 
@@ -485,7 +505,7 @@ create_script_for_old_cluster_deletion(
 /*
  *     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)
@@ -497,7 +517,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");
 
@@ -505,6 +525,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 abd3d5f8a2a12614219098d2041a68c848a7346a..e8b48a4fab0a41531010c7a4d4532fac6b35cf80 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 204749b6509faf80d722795acdd8a604a27606cd..40f03d666f337867a5dcb53ff756a94d4cba5df1 100644 (file)
@@ -187,6 +187,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;