diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 07f49c75ab2cffa3b4ac1c21a017730abb0c0d72..04f98449bdabb777c6721148833c1a51e11d5089 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.62 2002/04/09 20:35:46 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.63 2002/04/11 05:32:02 petere Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -734,9 +734,6 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
 
 	/*
 	 * Validate userid, find out if he is superuser
-	 *
-	 * We do not use superuser_arg() here because we also need to check
-	 * usecatupd.
 	 */
 	tuple = SearchSysCache(SHADOWSYSID,
 						   ObjectIdGetDatum(userid),
@@ -744,11 +741,12 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
 	if (!HeapTupleIsValid(tuple))
 		elog(ERROR, "pg_class_aclcheck: invalid user id %u", userid);
 
-	usesuper = ((Form_pg_shadow) GETSTRUCT(tuple))->usesuper;
 	usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd;
 
 	ReleaseSysCache(tuple);
 
+	usesuper = superuser_arg(userid);
+
 	/*
 	 * Now get the relation's tuple from pg_class
 	 */
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 9d40d6a11e328e858f301a4a79dda5ed3d7272a4..a6072be07ad8f11388e6bc86ef97c131ada7ca97 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.85 2002/03/06 06:09:32 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.86 2002/04/11 05:32:03 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,7 +49,7 @@ static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
 			int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
 			TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
 			char *dbpath);
-static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb);
+static bool have_createdb_privilege(void);
 static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
 static bool remove_dbdirs(const char *real_loc, const char *altloc);
 
@@ -67,8 +67,6 @@ createdb(const char *dbname, const char *dbowner,
 	char	   *target_dir;
 	char		src_loc[MAXPGPATH];
 	char		buf[2 * MAXPGPATH + 100];
-	bool		use_super,
-				use_createdb;
 	Oid			src_dboid;
 	int4		src_owner;
 	int			src_encoding;
@@ -91,21 +89,17 @@ createdb(const char *dbname, const char *dbowner,
 	else
 		datdba = GetUserId();
 
-	/* check permission to create database */
-	if (!get_user_info(GetUserId(), &use_super, &use_createdb))
-		elog(ERROR, "current user name is invalid");
-
 	if (datdba == (int32) GetUserId())
 	{
 		/* creating database for self: can be superuser or createdb */
-		if (!use_createdb && !use_super)
+		if (!superuser() && !have_createdb_privilege())
 			elog(ERROR, "CREATE DATABASE: permission denied");
 	}
 	else
 	{
 		/* creating database for someone else: must be superuser */
 		/* note that the someone else need not have any permissions */
-		if (!use_super)
+		if (!superuser())
 			elog(ERROR, "CREATE DATABASE: permission denied");
 	}
 
@@ -143,7 +137,7 @@ createdb(const char *dbname, const char *dbowner,
 	 */
 	if (!src_istemplate)
 	{
-		if (!use_super && GetUserId() != src_owner)
+		if (!superuser() && GetUserId() != src_owner )
 			elog(ERROR, "CREATE DATABASE: permission to copy \"%s\" denied",
 				 dbtemplate);
 	}
@@ -332,7 +326,6 @@ dropdb(const char *dbname)
 {
 	int4		db_owner;
 	bool		db_istemplate;
-	bool		use_super;
 	Oid			db_id;
 	char	   *alt_loc;
 	char	   *nominal_loc;
@@ -350,9 +343,6 @@ dropdb(const char *dbname)
 	if (IsTransactionBlock())
 		elog(ERROR, "DROP DATABASE: may not be called in a transaction block");
 
-	if (!get_user_info(GetUserId(), &use_super, NULL))
-		elog(ERROR, "current user name is invalid");
-
 	/*
 	 * Obtain exclusive lock on pg_database.  We need this to ensure that
 	 * no new backend starts up in the target database while we are
@@ -368,7 +358,7 @@ dropdb(const char *dbname)
 					 &db_istemplate, NULL, NULL, NULL, dbpath))
 		elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname);
 
-	if (!use_super && GetUserId() != db_owner)
+	if (GetUserId() != db_owner && !superuser())
 		elog(ERROR, "DROP DATABASE: permission denied");
 
 	/*
@@ -605,25 +595,23 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
 }
 
 static bool
-get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb)
+have_createdb_privilege(void)
 {
 	HeapTuple	utup;
+	bool		retval;
 
 	utup = SearchSysCache(SHADOWSYSID,
-						  ObjectIdGetDatum(use_sysid),
+						  ObjectIdGetDatum(GetUserId()),
 						  0, 0, 0);
 
 	if (!HeapTupleIsValid(utup))
-		return false;
-
-	if (use_super)
-		*use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
-	if (use_createdb)
-		*use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
+		retval = true;
+	else
+		retval = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
 
 	ReleaseSysCache(utup);
 
-	return true;
+	return retval;
 }
 
 
diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c
index f677d64fd3e3615d85b3745d6282625a62702120..4a3f3de1c540fe197362cb154ef678de6691c6a1 100644
--- a/src/backend/utils/misc/superuser.c
+++ b/src/backend/utils/misc/superuser.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.20 2002/02/18 23:11:26 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.21 2002/04/11 05:32:03 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,6 +27,11 @@
 
 /*
  * The Postgres user running this command has Postgres superuser privileges
+ *
+ * All code should use either of these two functions to find out
+ * whether a given user is a superuser, rather than evaluating
+ * pg_shadow.usesuper directly, so that the escape hatch built in for
+ * the single-user case works.
  */
 bool
 superuser(void)
diff --git a/src/include/catalog/pg_shadow.h b/src/include/catalog/pg_shadow.h
index 2e8d5b771c5d96a48d3be1d75d64e0ab468fb39c..fd372ae7bf47592395553b715a1b42756ce32656 100644
--- a/src/include/catalog/pg_shadow.h
+++ b/src/include/catalog/pg_shadow.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_shadow.h,v 1.18 2002/03/01 22:45:17 petere Exp $
+ * $Id: pg_shadow.h,v 1.19 2002/04/11 05:32:03 petere Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -35,7 +35,7 @@ CATALOG(pg_shadow) BOOTSTRAP BKI_WITHOUT_OIDS
 	int4		usesysid;
 	bool		usecreatedb;
 	bool		usetrace;
-	bool		usesuper;
+	bool		usesuper;		/* read this field via superuser() only */
 	bool		usecatupd;
 	text		passwd;
 	int4		valuntil;