*** a/doc/src/sgml/func.sgml --- b/doc/src/sgml/func.sgml *************** *** 12349,12357 **** SET search_path TO schema , schema, .. has_table_privilege checks whether a user can access a table in a particular way. The user can be ! specified by name or by OID ! (pg_authid.oid), or if the argument is ! omitted current_user is assumed. The table can be specified by name or by OID. (Thus, there are actually six variants of has_table_privilege, which can be distinguished by --- 12349,12357 ---- has_table_privilege checks whether a user can access a table in a particular way. The user can be ! specified by name; as public, to indicate the PUBLIC pseudo-role; by OID ! (pg_authid.oid), or, if the argument is ! omitted, current_user is assumed. The table can be specified by name or by OID. (Thus, there are actually six variants of has_table_privilege, which can be distinguished by *************** *** 12497,12503 **** SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); pg_has_role checks whether a user can access a role in a particular way. Its argument possibilities ! are analogous to has_table_privilege. The desired access privilege type must evaluate to some combination of MEMBER or USAGE. --- 12497,12504 ---- pg_has_role checks whether a user can access a role in a particular way. Its argument possibilities ! are analogous to has_table_privilege, ! except that public is not allowed as user name. The desired access privilege type must evaluate to some combination of MEMBER or USAGE. *** a/src/backend/utils/adt/acl.c --- b/src/backend/utils/adt/acl.c *************** *** 113,118 **** static AclMode convert_role_priv_string(text *priv_type_text); --- 113,119 ---- static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode); static void RoleMembershipCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr); + static Oid get_role_oid_or_public(const char *rolname); /* *************** *** 1791,1797 **** has_table_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*rolename), false); tableoid = convert_table_name(tablename); mode = convert_table_priv_string(priv_type_text); --- 1792,1798 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*rolename)); tableoid = convert_table_name(tablename); mode = convert_table_priv_string(priv_type_text); *************** *** 1840,1846 **** has_table_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_table_priv_string(priv_type_text); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid))) --- 1841,1847 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_table_priv_string(priv_type_text); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid))) *************** *** 1998,2004 **** has_sequence_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*rolename), false); mode = convert_sequence_priv_string(priv_type_text); sequenceoid = convert_table_name(sequencename); if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE) --- 1999,2005 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*rolename)); mode = convert_sequence_priv_string(priv_type_text); sequenceoid = convert_table_name(sequencename); if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE) *************** *** 2058,2064 **** has_sequence_privilege_name_id(PG_FUNCTION_ARGS) AclResult aclresult; char relkind; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_sequence_priv_string(priv_type_text); relkind = get_rel_relkind(sequenceoid); if (relkind == '\0') --- 2059,2065 ---- AclResult aclresult; char relkind; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_sequence_priv_string(priv_type_text); relkind = get_rel_relkind(sequenceoid); if (relkind == '\0') *************** *** 2209,2215 **** has_any_column_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*rolename), false); tableoid = convert_table_name(tablename); mode = convert_column_priv_string(priv_type_text); --- 2210,2216 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*rolename)); tableoid = convert_table_name(tablename); mode = convert_column_priv_string(priv_type_text); *************** *** 2266,2272 **** has_any_column_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_column_priv_string(priv_type_text); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid))) --- 2267,2273 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_column_priv_string(priv_type_text); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid))) *************** *** 2451,2457 **** has_column_privilege_name_name_name(PG_FUNCTION_ARGS) AclMode mode; int privresult; ! roleid = get_role_oid(NameStr(*rolename), false); tableoid = convert_table_name(tablename); colattnum = convert_column_name(tableoid, column); mode = convert_column_priv_string(priv_type_text); --- 2452,2458 ---- AclMode mode; int privresult; ! roleid = get_role_oid_or_public(NameStr(*rolename)); tableoid = convert_table_name(tablename); colattnum = convert_column_name(tableoid, column); mode = convert_column_priv_string(priv_type_text); *************** *** 2479,2485 **** has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS) AclMode mode; int privresult; ! roleid = get_role_oid(NameStr(*rolename), false); tableoid = convert_table_name(tablename); mode = convert_column_priv_string(priv_type_text); --- 2480,2486 ---- AclMode mode; int privresult; ! roleid = get_role_oid_or_public(NameStr(*rolename)); tableoid = convert_table_name(tablename); mode = convert_column_priv_string(priv_type_text); *************** *** 2506,2512 **** has_column_privilege_name_id_name(PG_FUNCTION_ARGS) AclMode mode; int privresult; ! roleid = get_role_oid(NameStr(*username), false); colattnum = convert_column_name(tableoid, column); mode = convert_column_priv_string(priv_type_text); --- 2507,2513 ---- AclMode mode; int privresult; ! roleid = get_role_oid_or_public(NameStr(*username)); colattnum = convert_column_name(tableoid, column); mode = convert_column_priv_string(priv_type_text); *************** *** 2532,2538 **** has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS) AclMode mode; int privresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_column_priv_string(priv_type_text); privresult = column_privilege_check(tableoid, colattnum, roleid, mode); --- 2533,2539 ---- AclMode mode; int privresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_column_priv_string(priv_type_text); privresult = column_privilege_check(tableoid, colattnum, roleid, mode); *************** *** 2823,2829 **** has_database_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); databaseoid = convert_database_name(databasename); mode = convert_database_priv_string(priv_type_text); --- 2824,2830 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); databaseoid = convert_database_name(databasename); mode = convert_database_priv_string(priv_type_text); *************** *** 2872,2878 **** has_database_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_database_priv_string(priv_type_text); if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid))) --- 2873,2879 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_database_priv_string(priv_type_text); if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid))) *************** *** 3021,3027 **** has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); fdwid = convert_foreign_data_wrapper_name(fdwname); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); --- 3022,3028 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); fdwid = convert_foreign_data_wrapper_name(fdwname); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); *************** *** 3070,3076 **** has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode); --- 3071,3077 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode); *************** *** 3203,3209 **** has_function_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); functionoid = convert_function_name(functionname); mode = convert_function_priv_string(priv_type_text); --- 3204,3210 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); functionoid = convert_function_name(functionname); mode = convert_function_priv_string(priv_type_text); *************** *** 3252,3258 **** has_function_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_function_priv_string(priv_type_text); if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid))) --- 3253,3259 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_function_priv_string(priv_type_text); if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid))) *************** *** 3403,3409 **** has_language_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); languageoid = convert_language_name(languagename); mode = convert_language_priv_string(priv_type_text); --- 3404,3410 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); languageoid = convert_language_name(languagename); mode = convert_language_priv_string(priv_type_text); *************** *** 3452,3458 **** has_language_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_language_priv_string(priv_type_text); if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid))) --- 3453,3459 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_language_priv_string(priv_type_text); if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid))) *************** *** 3594,3600 **** has_schema_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); schemaoid = convert_schema_name(schemaname); mode = convert_schema_priv_string(priv_type_text); --- 3595,3601 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); schemaoid = convert_schema_name(schemaname); mode = convert_schema_priv_string(priv_type_text); *************** *** 3643,3649 **** has_schema_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_schema_priv_string(priv_type_text); if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid))) --- 3644,3650 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_schema_priv_string(priv_type_text); if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid))) *************** *** 3787,3793 **** has_server_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); serverid = convert_server_name(servername); mode = convert_server_priv_string(priv_type_text); --- 3788,3794 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); serverid = convert_server_name(servername); mode = convert_server_priv_string(priv_type_text); *************** *** 3836,3842 **** has_server_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_server_priv_string(priv_type_text); aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode); --- 3837,3843 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_server_priv_string(priv_type_text); aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode); *************** *** 3969,3975 **** has_tablespace_privilege_name_name(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); tablespaceoid = convert_tablespace_name(tablespacename); mode = convert_tablespace_priv_string(priv_type_text); --- 3970,3976 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); tablespaceoid = convert_tablespace_name(tablespacename); mode = convert_tablespace_priv_string(priv_type_text); *************** *** 4018,4024 **** has_tablespace_privilege_name_id(PG_FUNCTION_ARGS) AclMode mode; AclResult aclresult; ! roleid = get_role_oid(NameStr(*username), false); mode = convert_tablespace_priv_string(priv_type_text); aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); --- 4019,4025 ---- AclMode mode; AclResult aclresult; ! roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_tablespace_priv_string(priv_type_text); aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); *************** *** 4821,4823 **** get_role_oid(const char *rolname, bool missing_ok) --- 4822,4839 ---- errmsg("role \"%s\" does not exist", rolname))); return oid; } + + /* + * get_role_oid_or_public - As above, but return ACL_ID_PUBLIC if the + * role name is "public". + */ + static Oid + get_role_oid_or_public(const char *rolname) + { + Oid oid; + + if (strcmp(rolname, "public") == 0) + return ACL_ID_PUBLIC; + + return get_role_oid(rolname, false); + }