Skip to content

Commit

Permalink
Propagate SECURITY LABEL ON ROLE stmt
Browse files Browse the repository at this point in the history
initial commit
  • Loading branch information
naisila committed Nov 2, 2023
1 parent ea55516 commit fd7c32a
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/backend/distributed/commands/distribute_object_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,15 @@ static DistributeObjectOps Any_Rename = {
.address = NULL,
.markDistributed = false,
};
static DistributeObjectOps Any_SecLabel = {
.deparse = DeparseSecLabelStmt,
.qualify = NULL,
.preprocess = PreprocessSecLabelStmt,
.postprocess = PostprocessSecLabelStmt,
.operationType = DIST_OPS_ALTER,
.address = SecLabelStmtObjectAddress,
.markDistributed = false,
};
static DistributeObjectOps Attribute_Rename = {
.deparse = DeparseRenameAttributeStmt,
.qualify = QualifyRenameAttributeStmt,
Expand Down Expand Up @@ -2020,6 +2029,11 @@ GetDistributeObjectOps(Node *node)
return &Vacuum_Analyze;
}

case T_SecLabelStmt:
{
return &Any_SecLabel;
}

case T_RenameStmt:
{
RenameStmt *stmt = castNode(RenameStmt, node);
Expand Down
116 changes: 116 additions & 0 deletions src/backend/distributed/commands/seclabel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*-------------------------------------------------------------------------
*
* seclabel.c
*
* This file contains the logic of SECURITY LABEL statement propagation.
*
* Copyright (c) Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/

#include "postgres.h"

#include "distributed/commands.h"
#include "distributed/commands/utility_hook.h"
#include "distributed/coordinator_protocol.h"
#include "distributed/deparser.h"
#include "distributed/log_utils.h"
#include "distributed/metadata_sync.h"
#include "distributed/metadata/distobject.h"

/*
* PreprocessSecLabelStmt is executed before the statement is applied to the local
* postgres instance.
*
* In this stage we can prepare the commands that need to be run on all workers to assign
* security labels on distributed objects, currently supporting just Role objects.
*/
List *
PreprocessSecLabelStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext)
{
if (!IsCoordinator() || !ShouldPropagate())
{
return NIL;
}

SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);

List * objectAddresses = GetObjectAddressListFromParseTree(node, false, false);
if(!IsAnyObjectDistributed(objectAddresses))
{
return NIL;
}

if (secLabelStmt->objtype != OBJECT_ROLE)
{
if (EnableUnsupportedFeatureMessages)
{
ereport(NOTICE, (errmsg("not propagating SECURITY LABEL commands whose"
" object type is not role"),
errhint(
"Connect to worker nodes directly to manually run the same"
" SECURITY LABEL command after disabling DDL propagation.")));
}
return NIL;
}

if (!EnableCreateRolePropagation)
{
return NIL;
}

const char *sql = DeparseTreeNode((Node *) secLabelStmt);

List *commandList = list_make3(DISABLE_DDL_PROPAGATION,
(void *) sql,
ENABLE_DDL_PROPAGATION);

return NodeDDLTaskList(NON_COORDINATOR_NODES, commandList);
}

/*
* PostprocessSecLabelStmt
*/
List *
PostprocessSecLabelStmt(Node *node, const char *queryString)
{
if (!EnableCreateRolePropagation || !IsCoordinator() || !ShouldPropagate())
{
return NIL;
}

SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);

if (secLabelStmt->objtype != OBJECT_ROLE)
{
return NIL;
}

List * objectAddresses = GetObjectAddressListFromParseTree(node, false, false);
if(IsAnyObjectDistributed(objectAddresses))
{
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
}

return NIL;
}


/*
* SecLabelStmtObjectAddress
*/
List *
SecLabelStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
{
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);

Relation rel = NULL; /* not used, but required to pass to get_object_address */
ObjectAddress address = get_object_address(secLabelStmt->objtype, secLabelStmt->object, &rel,
AccessShareLock, missing_ok);

ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
*addressPtr = address;
return list_make1(addressPtr);
}
76 changes: 76 additions & 0 deletions src/backend/distributed/deparser/deparse_seclabel_stmts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*-------------------------------------------------------------------------
*
* deparse_seclabel_stmts.c
* All routines to deparse SECURITY LABEL statements.
*
* Copyright (c), Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/

#include "postgres.h"

#include "distributed/deparser.h"
#include "nodes/parsenodes.h"

static void AppendSecLabelStmt(StringInfo buf, SecLabelStmt *stmt);

/*
* DeparseSecLabelStmt builds and returns a string representing of the
* SecLabelStmt for application on a remote server.
*/
char *
DeparseSecLabelStmt(Node *node)
{
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
StringInfoData buf = { 0 };
initStringInfo(&buf);

AppendSecLabelStmt(&buf, secLabelStmt);

return buf.data;
}


/*
* AppendSecLabelStmt generates the string representation of the
* SecLabelStmt and appends it to the buffer.
*/
static void
AppendSecLabelStmt(StringInfo buf, SecLabelStmt *stmt)
{
appendStringInfoString(buf, "SECURITY LABEL ");

if (stmt->provider != NULL)
{
appendStringInfo(buf, "FOR %s ", stmt->provider);
}

appendStringInfoString(buf, "ON ");

switch (stmt->objtype)
{
case OBJECT_ROLE:
{
appendStringInfo(buf, "ROLE %s ", strVal(castNode(String, stmt->object)));
break;
}

default:
{
ereport(ERROR, (errmsg("unsupported security label statement for"
" deparsing")));
}
}

appendStringInfoString(buf, "IS ");

if (stmt->label != NULL)
{
appendStringInfo(buf, "%s", stmt->label);
}
else
{
appendStringInfoString(buf, "NULL");
}
}
6 changes: 6 additions & 0 deletions src/include/distributed/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ extern List * AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok,
extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool
isPostprocess);

/* seclabel.c - forward declarations*/
extern List * PreprocessSecLabelStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext);
extern List * PostprocessSecLabelStmt(Node *node, const char *queryString);
extern List * SecLabelStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess);

/* sequence.c - forward declarations */
extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext);
Expand Down
3 changes: 3 additions & 0 deletions src/include/distributed/deparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ extern void QualifyRenameTextSearchDictionaryStmt(Node *node);
extern void QualifyTextSearchConfigurationCommentStmt(Node *node);
extern void QualifyTextSearchDictionaryCommentStmt(Node *node);

/* forward declarations for deparse_seclabel_stmts.c */
extern char * DeparseSecLabelStmt(Node *node);

/* forward declarations for deparse_sequence_stmts.c */
extern char * DeparseDropSequenceStmt(Node *node);
extern char * DeparseRenameSequenceStmt(Node *node);
Expand Down

0 comments on commit fd7c32a

Please sign in to comment.