mirror of https://github.com/citusdata/citus.git
Merge c4c7194ff0
into 4cd8bb1b67
commit
57b939899e
|
@ -810,6 +810,20 @@ static DistributeObjectOps Index_Drop = {
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
static DistributeObjectOps Parameter_Grant = {
|
||||||
|
.deparse = DeparseGrantOnParameterStmt,
|
||||||
|
.qualify = NULL,
|
||||||
|
.preprocess = NULL,
|
||||||
|
.postprocess = PostprocessGrantParameterStmt,
|
||||||
|
.objectType = OBJECT_PARAMETER_ACL,
|
||||||
|
.operationType = DIST_OPS_ALTER,
|
||||||
|
.address = NULL,
|
||||||
|
.markDistributed = false,
|
||||||
|
};
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
||||||
|
|
||||||
static DistributeObjectOps Policy_Drop = {
|
static DistributeObjectOps Policy_Drop = {
|
||||||
.deparse = NULL,
|
.deparse = NULL,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
|
@ -2117,6 +2131,13 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Database_Grant;
|
return &Database_Grant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
case OBJECT_PARAMETER_ACL:
|
||||||
|
{
|
||||||
|
return &Parameter_Grant;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return &Any_Grant;
|
return &Any_Grant;
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
#include "access/genam.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_parameter_acl.h"
|
||||||
|
#include "commands/defrem.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/grant_utils.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
|
||||||
|
static List * GenerateGrantOnParameterFromAclItem(char *parameterName, AclItem *aclItem);
|
||||||
|
static bool HasAclGrantOption(AclItem *aclItem, AclMode aclMode);
|
||||||
|
static void ValidatePermissionsAndGrants(AclItem *aclItem, AclMode modes[], int numModes);
|
||||||
|
static void CheckAndAppendGrantParameterQuery(List **queries, AclItem *aclItem, Oid
|
||||||
|
granteeOid,
|
||||||
|
char *parameterName, AclMode mode,
|
||||||
|
char *modeStr);
|
||||||
|
static void RemoveSemicolonFromEnd(char *query);
|
||||||
|
|
||||||
|
|
||||||
|
List *
|
||||||
|
PostprocessGrantParameterStmt(Node *node, const char *queryString)
|
||||||
|
{
|
||||||
|
if (!ShouldPropagate())
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsurePropagationToCoordinator();
|
||||||
|
|
||||||
|
char *command = DeparseTreeNode(node);
|
||||||
|
|
||||||
|
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
(void *) command,
|
||||||
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
|
return NodeDDLTaskList(REMOTE_NODES, commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateGrantOnParameterFromAclItem generates the grant queries for the given aclItem.
|
||||||
|
* First it sets the current role to the grantor of the aclItem, then it appends the grant
|
||||||
|
* privilege queries for the aclItem, and finally it resets the role to the original role.
|
||||||
|
* Ex: If the aclItem has the grant option for ACL_SET, it generates the following queries:
|
||||||
|
* SET ROLE <grantor>;
|
||||||
|
* GRANT SET ON <parameterName> TO <grantee>;
|
||||||
|
* RESET ROLE;
|
||||||
|
*/
|
||||||
|
static List *
|
||||||
|
GenerateGrantOnParameterFromAclItem(char *parameterName, AclItem *aclItem)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* seems unlikely but we check if there is a grant option in the list without the actual permission
|
||||||
|
*/
|
||||||
|
ValidatePermissionsAndGrants(aclItem, (AclMode[]) { ACL_SET, ACL_ALTER_SYSTEM }, 2);
|
||||||
|
Oid granteeOid = aclItem->ai_grantee;
|
||||||
|
List *queries = NIL;
|
||||||
|
|
||||||
|
queries = lappend(queries, GenerateSetRoleQuery(aclItem->ai_grantor));
|
||||||
|
|
||||||
|
CheckAndAppendGrantParameterQuery(&queries, aclItem, granteeOid, parameterName,
|
||||||
|
ACL_SET, "SET");
|
||||||
|
CheckAndAppendGrantParameterQuery(&queries, aclItem, granteeOid, parameterName,
|
||||||
|
ACL_ALTER_SYSTEM,
|
||||||
|
"ALTER SYSTEM");
|
||||||
|
|
||||||
|
queries = lappend(queries, "RESET ROLE");
|
||||||
|
|
||||||
|
return queries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CheckAndAppendGrantParameterQuery checks if the aclItem has the given mode and if it has, it appends the
|
||||||
|
* corresponding query to the queries list.
|
||||||
|
* Ex: If the mode is ACL_SET, it appends the query "GRANT SET ON <parameterName> TO <grantee>"
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
CheckAndAppendGrantParameterQuery(List **queries, AclItem *aclItem, Oid granteeOid,
|
||||||
|
char *parameterName,
|
||||||
|
AclMode mode, char *modeStr)
|
||||||
|
{
|
||||||
|
AclResult aclresult = pg_parameter_aclcheck(parameterName, granteeOid, mode);
|
||||||
|
if (aclresult == ACLCHECK_OK)
|
||||||
|
{
|
||||||
|
char *query = DeparseTreeNode((Node *) GenerateGrantStmtForRightsWithObjectName(
|
||||||
|
OBJECT_PARAMETER_ACL, granteeOid, parameterName,
|
||||||
|
modeStr,
|
||||||
|
HasAclGrantOption(aclItem, mode)));
|
||||||
|
|
||||||
|
RemoveSemicolonFromEnd(query);
|
||||||
|
|
||||||
|
*queries = lappend(*queries, query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RemoveSemicolonFromEnd removes the semicolon at the end of the query if it exists.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
RemoveSemicolonFromEnd(char *query)
|
||||||
|
{
|
||||||
|
/* remove the semicolon at the end of the query since it is already */
|
||||||
|
/* appended in metadata_sync phase */
|
||||||
|
if (query[strlen(query) - 1] == ';')
|
||||||
|
{
|
||||||
|
query[strlen(query) - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ValidatePermissionsAndGrants validates if the aclItem has the valid permissions and grants
|
||||||
|
* for the given modes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ValidatePermissionsAndGrants(AclItem *aclItem, AclMode modes[], int numModes)
|
||||||
|
{
|
||||||
|
AclMode permissions = ACLITEM_GET_PRIVS(*aclItem) & ACL_ALL_RIGHTS_PARAMETER_ACL;
|
||||||
|
AclMode grants = ACLITEM_GET_GOPTIONS(*aclItem) & ACL_ALL_RIGHTS_PARAMETER_ACL;
|
||||||
|
|
||||||
|
for (int i = 0; i < numModes; i++)
|
||||||
|
{
|
||||||
|
AclMode mode = modes[i];
|
||||||
|
if ((grants & mode) && !(permissions & mode))
|
||||||
|
{
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
|
ereport(ERROR, (errmsg("ACL item has no grant option for mode %lu", mode)));
|
||||||
|
#else
|
||||||
|
ereport(ERROR, (errmsg("ACL item has no grant option for mode %u", mode)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HasAclGrantOption checks if the aclItem has the grant option for the given mode.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
HasAclGrantOption(AclItem *aclItem, AclMode aclMode)
|
||||||
|
{
|
||||||
|
return (aclItem->ai_privs & ACL_GRANT_OPTION_FOR(aclMode)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateGrantStmtOnParametersFromCatalogTable generates the grant statements for the parameters
|
||||||
|
* from the pg_parameter_acl catalog table.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GenerateGrantStmtOnParametersFromCatalogTable(void)
|
||||||
|
{
|
||||||
|
/* Open pg_shdescription catalog */
|
||||||
|
Relation paramPermissionRelation = table_open(ParameterAclRelationId,
|
||||||
|
AccessShareLock);
|
||||||
|
|
||||||
|
|
||||||
|
int scanKeyCount = 0;
|
||||||
|
bool indexOk = false;
|
||||||
|
SysScanDesc scan = systable_beginscan(paramPermissionRelation, InvalidOid,
|
||||||
|
indexOk, NULL, scanKeyCount, NULL);
|
||||||
|
HeapTuple tuple;
|
||||||
|
List *commands = NIL;
|
||||||
|
while ((tuple = systable_getnext(scan)) != NULL)
|
||||||
|
{
|
||||||
|
bool isNull = false;
|
||||||
|
|
||||||
|
TupleDesc tupdesc = RelationGetDescr(paramPermissionRelation);
|
||||||
|
|
||||||
|
Datum aclDatum = heap_getattr(tuple, Anum_pg_parameter_acl_paracl, tupdesc,
|
||||||
|
&isNull);
|
||||||
|
Datum parameterNameDatum = heap_getattr(tuple, Anum_pg_parameter_acl_parname,
|
||||||
|
tupdesc,
|
||||||
|
&isNull);
|
||||||
|
|
||||||
|
char *parameterName = TextDatumGetCString(parameterNameDatum);
|
||||||
|
|
||||||
|
Acl *acl = DatumGetAclPCopy(aclDatum);
|
||||||
|
AclItem *aclDat = ACL_DAT(acl);
|
||||||
|
int aclNum = ACL_NUM(acl);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < aclNum; i++)
|
||||||
|
{
|
||||||
|
commands = list_concat(commands,
|
||||||
|
GenerateGrantOnParameterFromAclItem(
|
||||||
|
parameterName, &aclDat[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End the scan and close the catalog */
|
||||||
|
systable_endscan(scan);
|
||||||
|
table_close(paramPermissionRelation, AccessShareLock);
|
||||||
|
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* deparse_database_stmts.c
|
||||||
|
* All routines to deparse parameter statements.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
|
||||||
|
static void AppendGrantParameters(StringInfo buf, GrantStmt *stmt);
|
||||||
|
static void AppendGrantOnParameterStmt(StringInfo buf, GrantStmt *stmt);
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendGrantParameters(StringInfo buf, GrantStmt *stmt)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " ON PARAMETER ");
|
||||||
|
|
||||||
|
DefElem *def = NULL;
|
||||||
|
foreach_ptr(def, stmt->objects)
|
||||||
|
{
|
||||||
|
char *parameter = strVal(def);
|
||||||
|
appendStringInfoString(buf, quote_identifier(parameter));
|
||||||
|
if (def != (DefElem *) lfirst(list_tail(stmt->objects)))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendGrantOnParameterStmt(StringInfo buf, GrantStmt *stmt)
|
||||||
|
{
|
||||||
|
Assert(stmt->objtype == OBJECT_PARAMETER_ACL);
|
||||||
|
|
||||||
|
AppendGrantSharedPrefix(buf, stmt);
|
||||||
|
|
||||||
|
AppendGrantParameters(buf, stmt);
|
||||||
|
|
||||||
|
AppendGrantSharedSuffix(buf, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
DeparseGrantOnParameterStmt(Node *node)
|
||||||
|
{
|
||||||
|
GrantStmt *stmt = castNode(GrantStmt, node);
|
||||||
|
Assert(stmt->objtype == OBJECT_PARAMETER_ACL);
|
||||||
|
|
||||||
|
StringInfoData str = { 0 };
|
||||||
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
AppendGrantOnParameterStmt(&str, stmt);
|
||||||
|
|
||||||
|
return str.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
|
@ -65,6 +65,7 @@
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/distribution_column.h"
|
#include "distributed/distribution_column.h"
|
||||||
|
#include "distributed/grant_utils.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
#include "distributed/metadata/dependency.h"
|
#include "distributed/metadata/dependency.h"
|
||||||
|
@ -115,11 +116,6 @@ static bool SyncNodeMetadataSnapshotToNode(WorkerNode *workerNode, bool raiseOnE
|
||||||
static void DropMetadataSnapshotOnNode(WorkerNode *workerNode);
|
static void DropMetadataSnapshotOnNode(WorkerNode *workerNode);
|
||||||
static char * CreateSequenceDependencyCommand(Oid relationId, Oid sequenceId,
|
static char * CreateSequenceDependencyCommand(Oid relationId, Oid sequenceId,
|
||||||
char *columnName);
|
char *columnName);
|
||||||
static GrantStmt * GenerateGrantStmtForRights(ObjectType objectType,
|
|
||||||
Oid roleOid,
|
|
||||||
Oid objectId,
|
|
||||||
char *permission,
|
|
||||||
bool withGrantOption);
|
|
||||||
static List * GetObjectsForGrantStmt(ObjectType objectType, Oid objectId);
|
static List * GetObjectsForGrantStmt(ObjectType objectType, Oid objectId);
|
||||||
static AccessPriv * GetAccessPrivObjectForGrantStmt(char *permission);
|
static AccessPriv * GetAccessPrivObjectForGrantStmt(char *permission);
|
||||||
static List * GenerateGrantOnSchemaQueriesFromAclItem(Oid schemaOid,
|
static List * GenerateGrantOnSchemaQueriesFromAclItem(Oid schemaOid,
|
||||||
|
@ -130,7 +126,6 @@ static List * GenerateGrantOnFunctionQueriesFromAclItem(Oid schemaOid,
|
||||||
static List * GrantOnSequenceDDLCommands(Oid sequenceOid);
|
static List * GrantOnSequenceDDLCommands(Oid sequenceOid);
|
||||||
static List * GenerateGrantOnSequenceQueriesFromAclItem(Oid sequenceOid,
|
static List * GenerateGrantOnSequenceQueriesFromAclItem(Oid sequenceOid,
|
||||||
AclItem *aclItem);
|
AclItem *aclItem);
|
||||||
static char * GenerateSetRoleQuery(Oid roleOid);
|
|
||||||
static void MetadataSyncSigTermHandler(SIGNAL_ARGS);
|
static void MetadataSyncSigTermHandler(SIGNAL_ARGS);
|
||||||
static void MetadataSyncSigAlrmHandler(SIGNAL_ARGS);
|
static void MetadataSyncSigAlrmHandler(SIGNAL_ARGS);
|
||||||
|
|
||||||
|
@ -2257,18 +2252,66 @@ GenerateGrantOnDatabaseFromAclItem(Oid databaseOid, AclItem *aclItem)
|
||||||
* The field `objects` of GrantStmt doesn't have a common structure for all types.
|
* The field `objects` of GrantStmt doesn't have a common structure for all types.
|
||||||
* Make sure you have added your object type to GetObjectsForGrantStmt.
|
* Make sure you have added your object type to GetObjectsForGrantStmt.
|
||||||
*/
|
*/
|
||||||
static GrantStmt *
|
GrantStmt *
|
||||||
GenerateGrantStmtForRights(ObjectType objectType,
|
GenerateGrantStmtForRights(ObjectType objectType,
|
||||||
Oid roleOid,
|
Oid roleOid,
|
||||||
Oid objectId,
|
Oid objectId,
|
||||||
char *permission,
|
char *permission,
|
||||||
bool withGrantOption)
|
bool withGrantOption)
|
||||||
{
|
{
|
||||||
|
return BaseGenerateGrantStmtForRights(objectType, roleOid, objectId, NULL, permission,
|
||||||
|
withGrantOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateGrantStmtForRightsWithObjectName is the function for creating
|
||||||
|
* GrantStmt's for all types of objects that are supported with object name.
|
||||||
|
* It takes parameters to fill a GrantStmt's fields and returns the GrantStmt.
|
||||||
|
* The field `objects` of GrantStmt doesn't have a common structure for all types.
|
||||||
|
* Make sure you have added your object type to GetObjectsForGrantStmt.
|
||||||
|
*/
|
||||||
|
GrantStmt *
|
||||||
|
GenerateGrantStmtForRightsWithObjectName(ObjectType objectType,
|
||||||
|
Oid roleOid,
|
||||||
|
char *objectName,
|
||||||
|
char *permission,
|
||||||
|
bool withGrantOption)
|
||||||
|
{
|
||||||
|
return BaseGenerateGrantStmtForRights(objectType, roleOid, InvalidOid, objectName,
|
||||||
|
permission, withGrantOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BaseGenerateGrantStmtForRights is the base function for creating
|
||||||
|
* GrantStmt's for all types of objects that are supported with object .
|
||||||
|
* It is used by GenerateGrantStmtForRights and GenerateGrantStmtForRightsWithObjectName
|
||||||
|
* to support both object id and object name.
|
||||||
|
*/
|
||||||
|
GrantStmt *
|
||||||
|
BaseGenerateGrantStmtForRights(ObjectType objectType,
|
||||||
|
Oid roleOid,
|
||||||
|
Oid objectId,
|
||||||
|
char *objectName,
|
||||||
|
char *permission,
|
||||||
|
bool withGrantOption)
|
||||||
|
{
|
||||||
|
/*either objectId or objectName should be valid */
|
||||||
|
Assert(objectId != InvalidOid || objectName != NULL);
|
||||||
|
|
||||||
GrantStmt *stmt = makeNode(GrantStmt);
|
GrantStmt *stmt = makeNode(GrantStmt);
|
||||||
stmt->is_grant = true;
|
stmt->is_grant = true;
|
||||||
stmt->targtype = ACL_TARGET_OBJECT;
|
stmt->targtype = ACL_TARGET_OBJECT;
|
||||||
stmt->objtype = objectType;
|
stmt->objtype = objectType;
|
||||||
stmt->objects = GetObjectsForGrantStmt(objectType, objectId);
|
if (objectId != InvalidOid)
|
||||||
|
{
|
||||||
|
stmt->objects = GetObjectsForGrantStmt(objectType, objectId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stmt->objects = list_make1(makeString(objectName));
|
||||||
|
}
|
||||||
stmt->privileges = list_make1(GetAccessPrivObjectForGrantStmt(permission));
|
stmt->privileges = list_make1(GetAccessPrivObjectForGrantStmt(permission));
|
||||||
stmt->grantees = list_make1(GetRoleSpecObjectForUser(roleOid));
|
stmt->grantees = list_make1(GetRoleSpecObjectForUser(roleOid));
|
||||||
stmt->grant_option = withGrantOption;
|
stmt->grant_option = withGrantOption;
|
||||||
|
@ -2661,7 +2704,7 @@ SetLocalEnableMetadataSync(bool state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
char *
|
||||||
GenerateSetRoleQuery(Oid roleOid)
|
GenerateSetRoleQuery(Oid roleOid)
|
||||||
{
|
{
|
||||||
StringInfo buf = makeStringInfo();
|
StringInfo buf = makeStringInfo();
|
||||||
|
@ -4779,6 +4822,10 @@ PropagateNodeWideObjectsCommandList(void)
|
||||||
List *alterRoleSetCommands = GenerateAlterRoleSetCommandForRole(InvalidOid);
|
List *alterRoleSetCommands = GenerateAlterRoleSetCommandForRole(InvalidOid);
|
||||||
ddlCommands = list_concat(ddlCommands, alterRoleSetCommands);
|
ddlCommands = list_concat(ddlCommands, alterRoleSetCommands);
|
||||||
}
|
}
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
List *grantOnParameterCommands = GenerateGrantStmtOnParametersFromCatalogTable();
|
||||||
|
ddlCommands = list_concat(ddlCommands, grantOnParameterCommands);
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
||||||
|
|
||||||
return ddlCommands;
|
return ddlCommands;
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,6 +452,12 @@ extern List * PreprocessDropOwnedStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessReassignOwnedStmt(Node *node, const char *queryString);
|
extern List * PostprocessReassignOwnedStmt(Node *node, const char *queryString);
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
|
||||||
|
/* parameter.c - forward declarations */
|
||||||
|
extern List * PostprocessGrantParameterStmt(Node *node, const char *queryString);
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
||||||
|
|
||||||
/* policy.c - forward declarations */
|
/* policy.c - forward declarations */
|
||||||
extern List * CreatePolicyCommands(Oid relationId);
|
extern List * CreatePolicyCommands(Oid relationId);
|
||||||
extern void ErrorIfUnsupportedPolicy(Relation relation);
|
extern void ErrorIfUnsupportedPolicy(Relation relation);
|
||||||
|
|
|
@ -259,6 +259,11 @@ extern char * DeparseCreateDatabaseStmt(Node *node);
|
||||||
extern char * DeparseDropDatabaseStmt(Node *node);
|
extern char * DeparseDropDatabaseStmt(Node *node);
|
||||||
extern char * DeparseAlterDatabaseRenameStmt(Node *node);
|
extern char * DeparseAlterDatabaseRenameStmt(Node *node);
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
|
||||||
|
/* forward declarations for deparse_parameter_stmts.c*/
|
||||||
|
extern char * DeparseGrantOnParameterStmt(Node *node);
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
||||||
|
|
||||||
/* forward declaration for deparse_publication_stmts.c */
|
/* forward declaration for deparse_publication_stmts.c */
|
||||||
extern char * DeparseCreatePublicationStmt(Node *stmt);
|
extern char * DeparseCreatePublicationStmt(Node *stmt);
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* grant_utils.h
|
||||||
|
*
|
||||||
|
* Routines for grant operations.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef CITUS_GRANT_UTILS_H
|
||||||
|
#define CITUS_GRANT_UTILS_H
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
extern List * GenerateGrantStmtOnParametersFromCatalogTable(void);
|
||||||
|
#endif /* PG_VERSION_NUM >= PG_VERSION_15 */
|
||||||
|
|
||||||
|
extern char * GenerateSetRoleQuery(Oid roleOid);
|
||||||
|
extern GrantStmt * GenerateGrantStmtForRights(ObjectType objectType,
|
||||||
|
Oid roleOid,
|
||||||
|
Oid objectId,
|
||||||
|
char *permission,
|
||||||
|
bool withGrantOption);
|
||||||
|
extern GrantStmt * GenerateGrantStmtForRightsWithObjectName(ObjectType objectType,
|
||||||
|
Oid roleOid,
|
||||||
|
char *objectName,
|
||||||
|
char *permission,
|
||||||
|
bool withGrantOption);
|
||||||
|
extern GrantStmt * BaseGenerateGrantStmtForRights(ObjectType objectType,
|
||||||
|
Oid roleOid,
|
||||||
|
Oid objectId,
|
||||||
|
char *objectName,
|
||||||
|
char *permission,
|
||||||
|
bool withGrantOption);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CITUS_GRANT_UTILS_H */
|
|
@ -0,0 +1,254 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
||||||
|
\gset
|
||||||
|
\if :server_version_ge_15
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
create user grant_param_user1;
|
||||||
|
create user grant_param_user2;
|
||||||
|
create user grant_param_user3;
|
||||||
|
create user grant_param_user4;
|
||||||
|
create user "grant_param_user5-\!";
|
||||||
|
--test the grant command with all options
|
||||||
|
SET citus.log_remote_commands to on;
|
||||||
|
SET citus.grep_remote_commands = '%GRANT%';
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user1,grant_param_user2,"grant_param_user5-\!" WITH GRANT OPTION GRANTED BY CURRENT_USER;
|
||||||
|
NOTICE: issuing GRANT set, alter system ON PARAMETER max_connections, shared_buffers TO grant_param_user1, grant_param_user2, "grant_param_user5-\!" WITH GRANT OPTION GRANTED BY postgres;
|
||||||
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
NOTICE: issuing GRANT set, alter system ON PARAMETER max_connections, shared_buffers TO grant_param_user1, grant_param_user2, "grant_param_user5-\!" WITH GRANT OPTION GRANTED BY postgres;
|
||||||
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
RESET citus.log_remote_commands;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user1','grant_param_user2','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(t,grant_param_user1,max_connections,SET)
|
||||||
|
(t,grant_param_user1,max_connections,SET)
|
||||||
|
(t,grant_param_user1,max_connections,SET)
|
||||||
|
(t,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user1,shared_buffers,SET)
|
||||||
|
(t,grant_param_user1,shared_buffers,SET)
|
||||||
|
(t,grant_param_user1,shared_buffers,SET)
|
||||||
|
(t,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,max_connections,SET)
|
||||||
|
(t,grant_param_user2,max_connections,SET)
|
||||||
|
(t,grant_param_user2,max_connections,SET)
|
||||||
|
(t,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,shared_buffers,SET)
|
||||||
|
(t,grant_param_user2,shared_buffers,SET)
|
||||||
|
(t,grant_param_user2,shared_buffers,SET)
|
||||||
|
(t,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(36 rows)
|
||||||
|
|
||||||
|
--test the grant command admin option using grant_param_user1 with granted by
|
||||||
|
set role grant_param_user1;
|
||||||
|
SET citus.log_remote_commands to on;
|
||||||
|
GRANT ALL ON PARAMETER max_connections,shared_buffers TO grant_param_user3 GRANTED BY grant_param_user1;
|
||||||
|
NOTICE: issuing GRANT ALL PRIVILEGES ON PARAMETER max_connections, shared_buffers TO grant_param_user3 GRANTED BY grant_param_user1;
|
||||||
|
DETAIL: on server grant_param_user1@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
NOTICE: issuing GRANT ALL PRIVILEGES ON PARAMETER max_connections, shared_buffers TO grant_param_user3 GRANTED BY grant_param_user1;
|
||||||
|
DETAIL: on server grant_param_user1@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(12 rows)
|
||||||
|
|
||||||
|
reset role;
|
||||||
|
--test the revoke command grant option with all options
|
||||||
|
REVOKE GRANT OPTION FOR SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user1,grant_param_user2,"grant_param_user5-\!" cascade;
|
||||||
|
NOTICE: issuing REVOKE GRANT OPTION FOR set, alter system ON PARAMETER max_connections, shared_buffers FROM grant_param_user1, grant_param_user2, "grant_param_user5-\!" CASCADE;
|
||||||
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
NOTICE: issuing REVOKE GRANT OPTION FOR set, alter system ON PARAMETER max_connections, shared_buffers FROM grant_param_user1, grant_param_user2, "grant_param_user5-\!" CASCADE;
|
||||||
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
--test if the admin option removed for the revoked user. Need to get error
|
||||||
|
SET ROLE "grant_param_user5-\!";
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3 GRANTED BY "grant_param_user5-\!";
|
||||||
|
WARNING: no privileges were granted for "max_connections"
|
||||||
|
WARNING: no privileges were granted for "shared_buffers"
|
||||||
|
NOTICE: issuing GRANT set, alter system ON PARAMETER max_connections, shared_buffers TO grant_param_user3 GRANTED BY "grant_param_user5-\!";
|
||||||
|
DETAIL: on server grant_param_user5-\!@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
NOTICE: issuing GRANT set, alter system ON PARAMETER max_connections, shared_buffers TO grant_param_user3 GRANTED BY "grant_param_user5-\!";
|
||||||
|
DETAIL: on server grant_param_user5-\!@localhost:xxxxx connectionId: xxxxxxx
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(12 rows)
|
||||||
|
|
||||||
|
RESET ROLE;
|
||||||
|
--test the revoke command
|
||||||
|
REVOKE SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user1,grant_param_user2,grant_param_user3,"grant_param_user5-\!";
|
||||||
|
RESET citus.log_remote_commands;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user1','grant_param_user2','grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(f,grant_param_user1,max_connections,SET)
|
||||||
|
(f,grant_param_user1,max_connections,SET)
|
||||||
|
(f,grant_param_user1,max_connections,SET)
|
||||||
|
(f,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user1,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user1,shared_buffers,SET)
|
||||||
|
(f,grant_param_user1,shared_buffers,SET)
|
||||||
|
(f,grant_param_user1,shared_buffers,SET)
|
||||||
|
(f,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user1,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,max_connections,SET)
|
||||||
|
(f,grant_param_user2,max_connections,SET)
|
||||||
|
(f,grant_param_user2,max_connections,SET)
|
||||||
|
(f,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,shared_buffers,SET)
|
||||||
|
(f,grant_param_user2,shared_buffers,SET)
|
||||||
|
(f,grant_param_user2,shared_buffers,SET)
|
||||||
|
(f,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user2,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,SET)
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,SET)
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(36 rows)
|
||||||
|
|
||||||
|
--test with single permission and single user
|
||||||
|
GRANT ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user4'],ARRAY['max_connections','shared_buffers'], ARRAY['ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(f,grant_param_user4,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user4,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user4,max_connections,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user4,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user4,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(f,grant_param_user4,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
|
--test metadata_sync
|
||||||
|
SELECT 1 FROM citus_remove_node('localhost', :worker_2_port);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3,"grant_param_user5-\!" WITH GRANT OPTION GRANTED BY CURRENT_USER;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(16 rows)
|
||||||
|
|
||||||
|
SELECT 1 FROM citus_add_node('localhost', :worker_2_port);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
check_parameter_privileges
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,SET)
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,max_connections,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,SET)
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,grant_param_user3,shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,SET)
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",max_connections,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,SET)
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(t,"grant_param_user5-\\!",shared_buffers,"ALTER SYSTEM")
|
||||||
|
(24 rows)
|
||||||
|
|
||||||
|
REVOKE SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user3,"grant_param_user5-\!" cascade;
|
||||||
|
--clean all resources
|
||||||
|
DROP USER grant_param_user1;
|
||||||
|
DROP USER grant_param_user2;
|
||||||
|
DROP USER grant_param_user3;
|
||||||
|
DROP USER grant_param_user4;
|
||||||
|
DROP USER "grant_param_user5-\!";
|
||||||
|
reset citus.log_remote_commands;
|
||||||
|
reset citus.grep_remote_commands;
|
|
@ -0,0 +1,9 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
||||||
|
\gset
|
||||||
|
\if :server_version_ge_15
|
||||||
|
\else
|
||||||
|
\q
|
|
@ -628,6 +628,25 @@ BEGIN
|
||||||
JOIN pg_dist_node USING (nodeid);
|
JOIN pg_dist_node USING (nodeid);
|
||||||
END;
|
END;
|
||||||
$func$ LANGUAGE plpgsql;
|
$func$ LANGUAGE plpgsql;
|
||||||
|
CREATE OR REPLACE FUNCTION check_parameter_privileges(users text[], parameters text[], permissions text[])
|
||||||
|
RETURNS TABLE ( res text, usr text, param text, perms text) AS $func$
|
||||||
|
DECLARE
|
||||||
|
u text;
|
||||||
|
p text;
|
||||||
|
perm text;
|
||||||
|
BEGIN
|
||||||
|
FOREACH u IN ARRAY users
|
||||||
|
LOOP
|
||||||
|
FOREACH p IN ARRAY parameters
|
||||||
|
LOOP
|
||||||
|
FOREACH perm IN ARRAY permissions
|
||||||
|
LOOP
|
||||||
|
RETURN QUERY EXECUTE format($inner$SELECT result ,'%1$s','%2$s','%3$s' FROM run_command_on_all_nodes($$SELECT has_parameter_privilege('%1$s','%2$s', '%3$s'); $$)$inner$, u, p, perm);
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
CREATE OR REPLACE FUNCTION check_database_privileges(role_name text, db_name text, permissions text[])
|
CREATE OR REPLACE FUNCTION check_database_privileges(role_name text, db_name text, permissions text[])
|
||||||
RETURNS TABLE(permission text, result text)
|
RETURNS TABLE(permission text, result text)
|
||||||
AS $func$
|
AS $func$
|
||||||
|
|
|
@ -38,6 +38,7 @@ test: create_single_shard_table
|
||||||
test: create_drop_database_propagation
|
test: create_drop_database_propagation
|
||||||
test: create_drop_database_propagation_pg15
|
test: create_drop_database_propagation_pg15
|
||||||
test: create_drop_database_propagation_pg16
|
test: create_drop_database_propagation_pg16
|
||||||
|
test: grant_on_parameter_propagation
|
||||||
test: comment_on_database
|
test: comment_on_database
|
||||||
test: comment_on_role
|
test: comment_on_role
|
||||||
# don't parallelize single_shard_table_udfs to make sure colocation ids are sequential
|
# don't parallelize single_shard_table_udfs to make sure colocation ids are sequential
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
||||||
|
\gset
|
||||||
|
\if :server_version_ge_15
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
|
||||||
|
create user grant_param_user1;
|
||||||
|
create user grant_param_user2;
|
||||||
|
create user grant_param_user3;
|
||||||
|
create user grant_param_user4;
|
||||||
|
create user "grant_param_user5-\!";
|
||||||
|
|
||||||
|
|
||||||
|
--test the grant command with all options
|
||||||
|
SET citus.log_remote_commands to on;
|
||||||
|
SET citus.grep_remote_commands = '%GRANT%';
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user1,grant_param_user2,"grant_param_user5-\!" WITH GRANT OPTION GRANTED BY CURRENT_USER;
|
||||||
|
|
||||||
|
RESET citus.log_remote_commands;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user1','grant_param_user2','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
--test the grant command admin option using grant_param_user1 with granted by
|
||||||
|
set role grant_param_user1;
|
||||||
|
SET citus.log_remote_commands to on;
|
||||||
|
GRANT ALL ON PARAMETER max_connections,shared_buffers TO grant_param_user3 GRANTED BY grant_param_user1;
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
reset role;
|
||||||
|
|
||||||
|
--test the revoke command grant option with all options
|
||||||
|
REVOKE GRANT OPTION FOR SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user1,grant_param_user2,"grant_param_user5-\!" cascade;
|
||||||
|
|
||||||
|
--test if the admin option removed for the revoked user. Need to get error
|
||||||
|
SET ROLE "grant_param_user5-\!";
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3 GRANTED BY "grant_param_user5-\!";
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
RESET ROLE;
|
||||||
|
|
||||||
|
--test the revoke command
|
||||||
|
REVOKE SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user1,grant_param_user2,grant_param_user3,"grant_param_user5-\!";
|
||||||
|
|
||||||
|
RESET citus.log_remote_commands;
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user1','grant_param_user2','grant_param_user3'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
|
||||||
|
--test with single permission and single user
|
||||||
|
GRANT ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3;
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user4'],ARRAY['max_connections','shared_buffers'], ARRAY['ALTER SYSTEM']);
|
||||||
|
|
||||||
|
--test metadata_sync
|
||||||
|
|
||||||
|
SELECT 1 FROM citus_remove_node('localhost', :worker_2_port);
|
||||||
|
GRANT SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers TO grant_param_user3,"grant_param_user5-\!" WITH GRANT OPTION GRANTED BY CURRENT_USER;
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
SELECT 1 FROM citus_add_node('localhost', :worker_2_port);
|
||||||
|
|
||||||
|
SELECT check_parameter_privileges(ARRAY['grant_param_user3','grant_param_user5-\!'],ARRAY['max_connections','shared_buffers'], ARRAY['SET','ALTER SYSTEM']);
|
||||||
|
|
||||||
|
REVOKE SET,ALTER SYSTEM ON PARAMETER max_connections,shared_buffers FROM grant_param_user3,"grant_param_user5-\!" cascade;
|
||||||
|
|
||||||
|
|
||||||
|
--clean all resources
|
||||||
|
DROP USER grant_param_user1;
|
||||||
|
DROP USER grant_param_user2;
|
||||||
|
DROP USER grant_param_user3;
|
||||||
|
DROP USER grant_param_user4;
|
||||||
|
DROP USER "grant_param_user5-\!";
|
||||||
|
|
||||||
|
reset citus.log_remote_commands;
|
||||||
|
reset citus.grep_remote_commands;
|
|
@ -655,6 +655,26 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$func$ LANGUAGE plpgsql;
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION check_parameter_privileges(users text[], parameters text[], permissions text[])
|
||||||
|
RETURNS TABLE ( res text, usr text, param text, perms text) AS $func$
|
||||||
|
DECLARE
|
||||||
|
u text;
|
||||||
|
p text;
|
||||||
|
perm text;
|
||||||
|
BEGIN
|
||||||
|
FOREACH u IN ARRAY users
|
||||||
|
LOOP
|
||||||
|
FOREACH p IN ARRAY parameters
|
||||||
|
LOOP
|
||||||
|
FOREACH perm IN ARRAY permissions
|
||||||
|
LOOP
|
||||||
|
RETURN QUERY EXECUTE format($inner$SELECT result ,'%1$s','%2$s','%3$s' FROM run_command_on_all_nodes($$SELECT has_parameter_privilege('%1$s','%2$s', '%3$s'); $$)$inner$, u, p, perm);
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION check_database_privileges(role_name text, db_name text, permissions text[])
|
CREATE OR REPLACE FUNCTION check_database_privileges(role_name text, db_name text, permissions text[])
|
||||||
RETURNS TABLE(permission text, result text)
|
RETURNS TABLE(permission text, result text)
|
||||||
AS $func$
|
AS $func$
|
||||||
|
|
Loading…
Reference in New Issue