]> 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 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;