0001-Implement-COMMENT-ON-USER-MAPPING.patch
application/octet-stream
Filename: 0001-Implement-COMMENT-ON-USER-MAPPING.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: Implement COMMENT ON USER MAPPING.
| File | + | − |
|---|---|---|
| src/backend/catalog/aclchk.c | 43 | 0 |
| src/backend/catalog/objectaddress.c | 31 | 0 |
| src/backend/foreign/foreign.c | 36 | 0 |
| src/backend/parser/gram.y | 8 | 0 |
| src/include/foreign/foreign.h | 2 | 0 |
| src/include/nodes/parsenodes.h | 1 | 0 |
| src/include/utils/acl.h | 1 | 0 |
From 32a8bc339f47788293228a0f61f4f244ee969a51 Mon Sep 17 00:00:00 2001
From: Shigeru Hanada <hanada@metrosystems.co.jp>
Date: Mon, 4 Apr 2011 19:07:42 +0900
Subject: [PATCH 1/5] Implement COMMENT ON USER MAPPING.
Privilege to COMMENT is similar to ALTER/DROP USER MAPPING.
Needs updates for regression tests and documents.
---
src/backend/catalog/aclchk.c | 43 +++++++++++++++++++++++++++++++++++
src/backend/catalog/objectaddress.c | 31 +++++++++++++++++++++++++
src/backend/foreign/foreign.c | 36 +++++++++++++++++++++++++++++
src/backend/parser/gram.y | 8 ++++++
src/include/foreign/foreign.h | 2 +
src/include/nodes/parsenodes.h | 1 +
src/include/utils/acl.h | 1 +
7 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index aa3d59d..bbc6362 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -44,6 +44,7 @@
#include "catalog/pg_type.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_user_mapping.h"
#include "commands/dbcommands.h"
#include "commands/proclang.h"
#include "commands/tablespace.h"
@@ -4643,6 +4644,48 @@ pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid)
}
/*
+ * Ownership check for a user mapping (specified by OID).
+ *
+ * User mappings don't have owner, so we treat some users as the owner:
+ * (1) owner of the foreign server
+ * (2) user whose name matches the user name of the mapping exactly, and has
+ * USAGE privilege on the server.
+ */
+bool
+pg_user_mapping_ownercheck(Oid um_oid, Oid roleid)
+{
+ HeapTuple tuple;
+ Oid userId;
+ Oid serverId;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return true;
+
+ tuple = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(um_oid));
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("user mapping with OID %u does not exist",
+ um_oid)));
+
+ userId = ((Form_pg_user_mapping) GETSTRUCT(tuple))->umuser;
+ serverId = ((Form_pg_user_mapping) GETSTRUCT(tuple))->umserver;
+
+ ReleaseSysCache(tuple);
+
+ if (userId == roleid)
+ {
+ AclResult aclresult;
+
+ aclresult = pg_foreign_server_aclcheck(serverId, roleid, ACL_USAGE);
+ return (aclresult == ACLCHECK_OK);
+ }
+ else
+ return pg_foreign_server_ownercheck(serverId, roleid);
+}
+
+/*
* Ownership check for a database (specified by OID).
*/
bool
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 0d21d31..c322fd8 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -48,6 +48,7 @@
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
+#include "catalog/pg_user_mapping.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/extension.h"
@@ -232,6 +233,22 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
address.objectId = get_ts_config_oid(objname, false);
address.objectSubId = 0;
break;
+ case OBJECT_USER_MAPPING:
+ {
+ char *username;
+ char *servername;
+
+ Assert(list_length(objname) == 2);
+
+ username = strVal(linitial(objname));
+ servername = strVal(lsecond(objname));
+ address.classId = UserMappingRelationId;
+ address.objectId = get_user_mapping_oid(username,
+ servername,
+ false);
+ address.objectSubId = 0;
+ }
+ break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
/* placate compiler, in case it thinks elog might return */
@@ -682,6 +699,9 @@ object_exists(ObjectAddress address)
case ForeignServerRelationId:
cache = FOREIGNSERVEROID;
break;
+ case UserMappingRelationId:
+ cache = USERMAPPINGOID;
+ break;
case TSParserRelationId:
cache = TSPARSEROID;
break;
@@ -795,6 +815,17 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
NameListToString(objname));
break;
+ case OBJECT_USER_MAPPING:
+ if (!pg_user_mapping_ownercheck(address.objectId, roleid))
+ {
+ char *username = strVal(linitial(objname));
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be owner of user mapping FOR %s SERVER %s",
+ username ? username : "public",
+ strVal(lsecond(objname)))));
+ }
+ break;
case OBJECT_LANGUAGE:
if (!pg_language_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index cda90a6..a84358e 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -538,3 +538,39 @@ get_foreign_server_oid(const char *servername, bool missing_ok)
errmsg("server \"%s\" does not exist", servername)));
return oid;
}
+
+/*
+ * get_user_mapping_oid - given a USER name and SERVER name, look up the OID
+ *
+ * If missing_ok is false, throw an error if name not found. If true, just
+ * return InvalidOid.
+ */
+Oid
+get_user_mapping_oid(const char *username, const char *servername,
+ bool missing_ok)
+{
+ Oid useroid;
+ Oid serveroid;
+ Oid oid;
+
+ /* Determine umuser of the mapping */
+ if (username == NULL)
+ useroid = 0;
+ else if (strcmp(username, "current_user") == 0)
+ useroid = GetUserId();
+ else
+ useroid = get_role_oid(username, false);
+
+ /* Determine umserver of the mapping */
+ serveroid = get_foreign_server_oid(servername, false);
+
+ oid = GetSysCacheOid2(USERMAPPINGUSERSERVER,
+ ObjectIdGetDatum(useroid),
+ ObjectIdGetDatum(serveroid));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("user mapping \"%s\" for the server does not exist",
+ MappingUserName(useroid))));
+ return oid;
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a22ab66..c234259 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4954,6 +4954,14 @@ CommentStmt:
n->comment = $8;
$$ = (Node *) n;
}
+ | COMMENT ON USER MAPPING FOR auth_ident SERVER name IS comment_text
+ {
+ CommentStmt *n = makeNode(CommentStmt);
+ n->objtype = OBJECT_USER_MAPPING;
+ n->objname = list_make2(makeString($6), makeString($8));
+ n->comment = $10;
+ $$ = (Node *) n;
+ }
;
comment_type:
diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
index 2fda9e3..f94d940 100644
--- a/src/include/foreign/foreign.h
+++ b/src/include/foreign/foreign.h
@@ -78,5 +78,7 @@ extern ForeignTable *GetForeignTable(Oid relid);
extern Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok);
extern Oid get_foreign_server_oid(const char *servername, bool missing_ok);
+extern Oid get_user_mapping_oid(const char *username, const char *servername,
+ bool missing_ok);
#endif /* FOREIGN_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d9eac76..c464c49 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1133,6 +1133,7 @@ typedef enum ObjectType
OBJECT_TSPARSER,
OBJECT_TSTEMPLATE,
OBJECT_TYPE,
+ OBJECT_USER_MAPPING,
OBJECT_VIEW
} ObjectType;
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index b28b764..a74bad5 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -317,6 +317,7 @@ extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid);
extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid);
extern bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid);
extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid);
+extern bool pg_user_mapping_ownercheck(Oid um_oid, Oid roleid);
extern bool pg_extension_ownercheck(Oid ext_oid, Oid roleid);
extern bool has_createrole_privilege(Oid roleid);
--
1.7.3