aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/foreigncmds.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2009-01-20 09:10:20 +0000
committerPeter Eisentraut <peter_e@gmx.net>2009-01-20 09:10:20 +0000
commit93a6be63a55a8cd0d73b3fa81eb6a46013a3a974 (patch)
tree687e12b06f610c10bd3acf2210275fbeb7cdfb84 /src/backend/commands/foreigncmds.c
parentfe626982182bd1c8cd2606027a4d49a2f31a01c3 (diff)
downloadpostgresql-93a6be63a55a8cd0d73b3fa81eb6a46013a3a974.tar.gz
postgresql-93a6be63a55a8cd0d73b3fa81eb6a46013a3a974.zip
Revise the permission checking on user mapping DDL commands.
CREATE/ALTER/DROP USER MAPPING are now allowed either by the server owner or by a user with USAGE privileges for his own user name. This is more or less what the SQL standard wants anyway (plus "implementation-defined") Hide information_schema.user_mapping_options.option_value, unless the current user is the one associated with the user mapping, or is the server owner and the mapping is for PUBLIC, or is a superuser. This is to protect passwords. Also, fix a bug in information_schema._pg_foreign_servers, which hid servers using wrappers where the current user did not have privileges on the wrapper. The correct behavior is to hide servers where the current user has no privileges on the server.
Diffstat (limited to 'src/backend/commands/foreigncmds.c')
-rw-r--r--src/backend/commands/foreigncmds.c56
1 files changed, 32 insertions, 24 deletions
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