diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index cc64d70930..4ab6717c7c 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 1b59e81a4c..c7535508a7 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)