From ab248c17856b718e2eec850d39e5e8c2c5bde696 Mon Sep 17 00:00:00 2001 From: Burak Velioglu Date: Fri, 4 Feb 2022 16:02:55 +0300 Subject: [PATCH] Check object ownership while creating pg_dist_object entries on remote --- .../metadata/pg_get_object_address_12_13_14.c | 189 +----------------- 1 file changed, 8 insertions(+), 181 deletions(-) diff --git a/src/backend/distributed/metadata/pg_get_object_address_12_13_14.c b/src/backend/distributed/metadata/pg_get_object_address_12_13_14.c index c2a8e29e3..c4da6764a 100644 --- a/src/backend/distributed/metadata/pg_get_object_address_12_13_14.c +++ b/src/backend/distributed/metadata/pg_get_object_address_12_13_14.c @@ -38,7 +38,6 @@ static void ErrorIfCurrentUserCanNotDistributeObject(ObjectType type, ObjectAddress *addr, Node *node, Relation *relation); -static void ErrorIfUserNotAllowedToPropagateExtension(char *extensionName); static List * textarray_to_strvaluelist(ArrayType *arr); /* It is defined on PG >= 13 versions by default */ @@ -398,9 +397,6 @@ ErrorIfCurrentUserCanNotDistributeObject(ObjectType type, ObjectAddress *addr, Node *node, Relation *relation) { Oid userId = GetUserId(); - AclMode aclMaskResult = 0; - bool skipAclCheck = false; - Oid idToCheck = InvalidOid; if (!SupportedDependencyByCitus(addr)) { @@ -410,27 +406,19 @@ ErrorIfCurrentUserCanNotDistributeObject(ObjectType type, ObjectAddress *addr, switch (type) { case OBJECT_SCHEMA: - { - idToCheck = addr->objectId; - aclMaskResult = pg_namespace_aclmask(idToCheck, userId, ACL_USAGE, - ACLMASK_ANY); - break; - } - + case OBJECT_DATABASE: case OBJECT_FUNCTION: case OBJECT_PROCEDURE: case OBJECT_AGGREGATE: + case OBJECT_TYPE: + case OBJECT_FOREIGN_SERVER: + case OBJECT_SEQUENCE: + case OBJECT_FOREIGN_TABLE: + case OBJECT_TABLE: + case OBJECT_EXTENSION: + case OBJECT_COLLATION: { check_object_ownership(userId, type, *addr, node, *relation); - skipAclCheck = true; - break; - } - - case OBJECT_DATABASE: - { - idToCheck = addr->objectId; - aclMaskResult = pg_database_aclmask(idToCheck, userId, ACL_CONNECT, - ACLMASK_ANY); break; } @@ -443,54 +431,6 @@ ErrorIfCurrentUserCanNotDistributeObject(ObjectType type, ObjectAddress *addr, "access privileges on role %d with type %d", addr->objectId, type))); } - skipAclCheck = true; - break; - } - - case OBJECT_TYPE: - { - idToCheck = addr->objectId; - aclMaskResult = pg_type_aclmask(idToCheck, userId, ACL_USAGE, - ACLMASK_ANY); - break; - } - - case OBJECT_FOREIGN_SERVER: - { - idToCheck = addr->objectId; - aclMaskResult = pg_foreign_server_aclmask(idToCheck, userId, ACL_USAGE, - ACLMASK_ANY); - break; - } - - case OBJECT_SEQUENCE: - { - idToCheck = addr->objectId; - aclMaskResult = pg_class_aclmask(idToCheck, userId, ACL_USAGE, ACLMASK_ANY); - break; - } - - case OBJECT_FOREIGN_TABLE: - case OBJECT_TABLE: - { - /* table distribution already does the ownership check, so we can stick to that over acl_check */ - check_object_ownership(userId, type, *addr, node, *relation); - skipAclCheck = true; - break; - } - - case OBJECT_EXTENSION: - { - Value *valueNode = (Value *) node; - char *extensionName = strVal(valueNode); - ErrorIfUserNotAllowedToPropagateExtension(extensionName); - skipAclCheck = true; - break; - } - - case OBJECT_COLLATION: - { - skipAclCheck = true; break; } @@ -501,119 +441,6 @@ ErrorIfCurrentUserCanNotDistributeObject(ObjectType type, ObjectAddress *addr, break; } } - - if (!skipAclCheck && aclMaskResult == ACL_NO_RIGHTS) - { - ereport(ERROR, (errmsg("Current user does not have required privileges " - "on %d with type id %d to distribute it", - idToCheck, type))); - } -} - - -/* - * ErrorIfUserNotAllowedToPropagateExtension errors out if the current user does - * not have required privileges to propagate extension - */ -static void -ErrorIfUserNotAllowedToPropagateExtension(char *extensionName) -{ - const int nameAttributeIndex = 1; - const int superuserAttributeIndex = 4; -#if PG_VERSION_NUM >= PG_VERSION_13 - const int trustedAttributeIndex = 5; -#endif - - LOCAL_FCINFO(fcinfo, 0); - FmgrInfo flinfo; - - bool goForward = true; - bool doCopy = false; - - EState *estate = CreateExecutorState(); - ReturnSetInfo *extensionsResultSet = makeNode(ReturnSetInfo); - extensionsResultSet->econtext = GetPerTupleExprContext(estate); - extensionsResultSet->allowedModes = SFRM_Materialize; - - fmgr_info(F_PG_AVAILABLE_EXTENSION_VERSIONS, &flinfo); - InitFunctionCallInfoData(*fcinfo, &flinfo, 0, InvalidOid, NULL, - (Node *) extensionsResultSet); - - /* - * pg_available_extensions_versions returns result set containing all - * available extension versions with whether the extension requires - * superuser and it is trusted information. - */ - (*pg_available_extension_versions)(fcinfo); - - TupleTableSlot *tupleTableSlot = MakeSingleTupleTableSlotCompat( - extensionsResultSet->setDesc, - &TTSOpsMinimalTuple); - bool hasTuple = tuplestore_gettupleslot(extensionsResultSet->setResult, - goForward, - doCopy, - tupleTableSlot); - while (hasTuple) - { - bool isNull = false; - Datum curExtensionNameDatum = slot_getattr(tupleTableSlot, - nameAttributeIndex, - &isNull); - char *curExtensionName = NameStr(*DatumGetName(curExtensionNameDatum)); - if (strcmp(extensionName, curExtensionName) == 0) - { - Datum superuserExpectedDatum = slot_getattr(tupleTableSlot, - superuserAttributeIndex, - &isNull); - bool superuserExpected = DatumGetBool(superuserExpectedDatum); - -#if PG_VERSION_NUM < PG_VERSION_13 - if (superuserExpected) - { - EnsureSuperUser(); - } -#else - if (superuserExpected) - { - /* - * After PG 13, if the extension is trusted it can be created - * by the user having CREATE privilege on the database even if - * the extension requires superuser. - */ - Datum trustedExtensionDatum = slot_getattr(tupleTableSlot, - trustedAttributeIndex, - &isNull); - bool trustedExtension = DatumGetBool(trustedExtensionDatum); - - if (trustedExtension) - { - /* Allow if user has CREATE privilege on current database */ - AclResult aclresult = pg_database_aclcheck(MyDatabaseId, - GetUserId(), - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - { - ereport(ERROR, (errmsg("operation is not allowed"), - errhint("Must have CREATE privilege " - "on database to propagate " - "extension %s", curExtensionName))); - } - } - else - { - EnsureSuperUser(); - } - } -#endif - break; - } - - ExecClearTuple(tupleTableSlot); - hasTuple = tuplestore_gettupleslot(extensionsResultSet->setResult, goForward, - doCopy, tupleTableSlot); - } - - ExecDropSingleTupleTableSlot(tupleTableSlot); }