diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/information_schema.sql | 17 | ||||
-rw-r--r-- | src/backend/commands/foreigncmds.c | 56 |
2 files changed, 43 insertions, 30 deletions
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 5bb46eedf8a..470a454f690 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -4,7 +4,7 @@ * * Copyright (c) 2003-2009, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.49 2009/01/14 21:12:09 petere Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.50 2009/01/20 09:10:20 petere Exp $ */ /* @@ -2465,12 +2465,12 @@ CREATE VIEW _pg_foreign_servers AS s.srvoptions, CAST(current_database() AS sql_identifier) AS foreign_server_catalog, CAST(srvname AS sql_identifier) AS foreign_server_name, - w.foreign_data_wrapper_catalog, - w.foreign_data_wrapper_name, + CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog, + CAST(w.fdwname AS sql_identifier) AS foreign_data_wrapper_name, CAST(srvtype AS character_data) AS foreign_server_type, CAST(srvversion AS character_data) AS foreign_server_version, CAST(u.rolname AS sql_identifier) AS authorization_identifier - FROM pg_foreign_server s, _pg_foreign_data_wrappers w, pg_authid u + FROM pg_foreign_server s, pg_foreign_data_wrapper w, pg_authid u WHERE w.oid = s.srvfdw AND u.oid = s.srvowner AND (pg_has_role(s.srvowner, 'USAGE') @@ -2512,9 +2512,11 @@ GRANT SELECT ON foreign_servers TO PUBLIC; CREATE VIEW _pg_user_mappings AS SELECT um.oid, um.umoptions, + um.umuser, CAST(COALESCE(u.rolname,'PUBLIC') AS sql_identifier ) AS authorization_identifier, s.foreign_server_catalog, - s.foreign_server_name + s.foreign_server_name, + s.authorization_identifier AS srvowner FROM pg_user_mapping um LEFT JOIN pg_authid u ON (u.oid = um.umuser), _pg_foreign_servers s WHERE s.oid = um.umserver; @@ -2529,7 +2531,10 @@ CREATE VIEW user_mapping_options AS foreign_server_catalog, foreign_server_name, CAST((pg_options_to_table(um.umoptions)).option_name AS sql_identifier) AS option_name, - CAST((pg_options_to_table(um.umoptions)).option_value AS character_data) AS option_value + CAST(CASE WHEN (umuser <> 0 AND authorization_identifier = current_user) + OR (umuser = 0 AND pg_has_role(srvowner, 'USAGE')) + OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) THEN (pg_options_to_table(um.umoptions)).option_value + ELSE NULL END AS character_data) AS option_value FROM _pg_user_mappings um; GRANT SELECT ON user_mapping_options TO PUBLIC; diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 17336c35f38..0967001aa3f 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.4 2009/01/01 17:23:38 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.5 2009/01/20 09:10:20 petere Exp $ * *------------------------------------------------------------------------- */ @@ -829,6 +829,33 @@ RemoveForeignServerById(Oid srvId) /* + * Common routine to check permission for user-mapping-related DDL + * commands. We allow server owners to operate on any mapping, and + * users to operate on their own mapping. + */ +static void +user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername) +{ + Oid curuserid = GetUserId(); + + if (!pg_foreign_server_ownercheck(serverid, curuserid)) + { + if (umuserid == curuserid) + { + AclResult aclresult; + + aclresult = pg_foreign_server_aclcheck(serverid, curuserid, ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_FOREIGN_SERVER, servername); + } + else + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, + servername); + } +} + + +/* * Create user mapping */ void @@ -841,24 +868,17 @@ CreateUserMapping(CreateUserMappingStmt *stmt) HeapTuple tuple; Oid useId; Oid umId; - Oid ownerId; ObjectAddress myself; ObjectAddress referenced; ForeignServer *srv; ForeignDataWrapper *fdw; - ownerId = GetUserId(); - useId = GetUserOidFromMapping(stmt->username, false); - /* - * Check that the server exists and that the we own it. - */ + /* Check that the server exists. */ srv = GetForeignServerByName(stmt->servername, false); - if (!pg_foreign_server_ownercheck(srv->serverid, ownerId)) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, - stmt->servername); + user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername); /* * Check that the user mapping is unique within server. @@ -951,12 +971,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt) errmsg("user mapping \"%s\" does not exist for the server", MappingUserName(useId)))); - /* - * Must be owner of the server to alter user mapping. - */ - if (!pg_foreign_server_ownercheck(srv->serverid, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, - stmt->servername); + user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername); tp = SearchSysCacheCopy(USERMAPPINGOID, ObjectIdGetDatum(umId), @@ -1071,14 +1086,7 @@ RemoveUserMapping(DropUserMappingStmt *stmt) return; } - /* - * Only allow DROP if we own the server. - */ - if (!pg_foreign_server_ownercheck(srv->serverid, GetUserId())) - { - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, - srv->servername); - } + user_mapping_ddl_aclcheck(useId, srv->serverid, srv->servername); /* * Do the deletion |