diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index cc64d7093086f16e93e40f79e9943ea173d0165b..4ab6717c7c8fc3769e3b2e996240349275eb4d07 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.100 2004/05/26 18:35:32 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.101 2004/05/28 16:17:14 tgl Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -1347,20 +1347,30 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
 		return mask;
 
 	/*
-	 * If we have been assigned this namespace as a temp
-	 * namespace, check to make sure we have CREATE permissions on
-	 * the database.
+	 * If we have been assigned this namespace as a temp namespace,
+	 * check to make sure we have CREATE TEMP permission on the database,
+	 * and if so act as though we have all standard (but not GRANT OPTION)
+	 * permissions on the namespace.  If we don't have CREATE TEMP, act as
+	 * though we have only USAGE (and not CREATE) rights.
 	 *
-	 * Instead of returning ACLCHECK_NO_PRIV, should we return via
-	 * ereport() with a message about trying to create an object
-	 * in a TEMP namespace when GetUserId() doesn't have perms?
+	 * This may seem redundant given the check in InitTempTableNamespace,
+	 * but it really isn't since current user ID may have changed since then.
+	 * The upshot of this behavior is that a SECURITY INVOKER function can
+	 * create temp tables that can then be accessed (if permission is granted)
+	 * by code that doesn't have permissions to create temp tables.
+	 *
+	 * XXX Would it be safe to ereport a special error message as
+	 * InitTempTableNamespace does?  Returning zero here means we'll get a
+	 * generic "permission denied for schema pg_temp_N" message, which is not
+	 * remarkably user-friendly.
 	 */
-	if (isTempNamespace(nsp_oid)) {
-	  if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
-				   ACL_CREATE_TEMP) == ACLCHECK_OK)
-	    return ACLCHECK_OK;
-	  else
-	    return ACLCHECK_NO_PRIV;
+	if (isTempNamespace(nsp_oid))
+	{
+		if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
+								 ACL_CREATE_TEMP) == ACLCHECK_OK)
+			return mask & ACL_ALL_RIGHTS_NAMESPACE;
+		else
+			return mask & ACL_USAGE;
 	}
 
 	/*
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 1b59e81a4c6fb606e63ee62ba4c780b7c7f1dd86..c7535508a7397198e87bd83bc5f3306db4fbcae8 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.65 2004/05/26 18:35:32 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.66 2004/05/28 16:17:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1640,9 +1640,10 @@ InitTempTableNamespace(void)
 	 * tables.	We use a nonstandard error message here since
 	 * "databasename: permission denied" might be a tad cryptic.
 	 *
-	 * ACL_CREATE_TEMP perms are also checked in
-	 * pg_namespace_aclcheck() that way only users who have TEMP
-	 * perms can create objects.
+	 * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
+	 * that's necessary since current user ID could change during the session.
+	 * But there's no need to make the namespace in the first place until a
+	 * temp table creation request is made by someone with appropriate rights.
 	 */
 	if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
 							 ACL_CREATE_TEMP) != ACLCHECK_OK)