Skip to content

Commit

Permalink
Adds grant/revoke privileges on database propagation (citusdata#7109)
Browse files Browse the repository at this point in the history
DESCRIPTION: Adds grant/revoke propagation support for database
privileges

Following the implementation of support for granting and revoking
database privileges, certain tests that issued grants for worker nodes
experienced failures. These ones are fixed in this PR as well.
  • Loading branch information
gurkanindibay authored Aug 24, 2023
1 parent 553780e commit 8d3a06c
Show file tree
Hide file tree
Showing 15 changed files with 1,544 additions and 69 deletions.
40 changes: 40 additions & 0 deletions src/backend/distributed/commands/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
static Oid get_database_owner(Oid db_oid);
List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext);

/* controlled via GUC */
bool EnableAlterDatabaseOwner = true;
Expand Down Expand Up @@ -107,3 +109,41 @@ get_database_owner(Oid db_oid)

return dba;
}


/*
* PreprocessGrantOnDatabaseStmt 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 grant
* on databases.
*/
List *
PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext)
{
if (!ShouldPropagate())
{
return NIL;
}

GrantStmt *stmt = castNode(GrantStmt, node);
Assert(stmt->objtype == OBJECT_DATABASE);

List *databaseList = stmt->objects;

if (list_length(databaseList) == 0)
{
return NIL;
}

EnsureCoordinator();

char *sql = DeparseTreeNode((Node *) stmt);

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

return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
}
17 changes: 17 additions & 0 deletions src/backend/distributed/commands/distribute_object_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,18 @@ static DistributeObjectOps Database_AlterOwner = {
.address = AlterDatabaseOwnerObjectAddress,
.markDistributed = false,
};

static DistributeObjectOps Database_Grant = {
.deparse = DeparseGrantOnDatabaseStmt,
.qualify = NULL,
.preprocess = PreprocessGrantOnDatabaseStmt,
.postprocess = NULL,
.objectType = OBJECT_DATABASE,
.operationType = DIST_OPS_ALTER,
.address = NULL,
.markDistributed = false,
};

static DistributeObjectOps Domain_Alter = {
.deparse = DeparseAlterDomainStmt,
.qualify = QualifyAlterDomainStmt,
Expand Down Expand Up @@ -1911,6 +1923,11 @@ GetDistributeObjectOps(Node *node)
return &Routine_Grant;
}

case OBJECT_DATABASE:
{
return &Database_Grant;
}

default:
{
return &Any_Grant;
Expand Down
76 changes: 76 additions & 0 deletions src/backend/distributed/deparser/deparse_database_stmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,79 @@ AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
quote_identifier(strVal((String *) stmt->object)),
RoleSpecString(stmt->newowner, true));
}


static void
AppendGrantDatabases(StringInfo buf, GrantStmt *stmt)
{
ListCell *cell = NULL;
appendStringInfo(buf, " ON DATABASE ");

foreach(cell, stmt->objects)
{
char *database = strVal(lfirst(cell));
appendStringInfoString(buf, quote_identifier(database));
if (cell != list_tail(stmt->objects))
{
appendStringInfo(buf, ", ");
}
}
}


static void
AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt)
{
Assert(stmt->objtype == OBJECT_DATABASE);

appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE");

if (!stmt->is_grant && stmt->grant_option)
{
appendStringInfo(buf, "GRANT OPTION FOR ");
}

AppendGrantPrivileges(buf, stmt);

AppendGrantDatabases(buf, stmt);

AppendGrantGrantees(buf, stmt);

if (stmt->is_grant && stmt->grant_option)
{
appendStringInfo(buf, " WITH GRANT OPTION");
}
if (!stmt->is_grant)
{
if (stmt->behavior == DROP_RESTRICT)
{
appendStringInfo(buf, " RESTRICT");
}
else if (stmt->behavior == DROP_CASCADE)
{
appendStringInfo(buf, " CASCADE");
}
}

if (stmt->grantor)
{
appendStringInfo(buf, " GRANTED BY %s", RoleSpecString(stmt->grantor, true));
}

appendStringInfo(buf, ";");
}


char *
DeparseGrantOnDatabaseStmt(Node *node)
{
GrantStmt *stmt = castNode(GrantStmt, node);
Assert(stmt->objtype == OBJECT_DATABASE);

StringInfoData str = { 0 };
initStringInfo(&str);

AppendGrantOnDatabaseStmt(&str, stmt);

return str.data;
}
4 changes: 4 additions & 0 deletions src/include/distributed/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ extern List * AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool
isPostprocess);
extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address);

extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext);

/* domain.c - forward declarations */
extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool
isPostprocess);
Expand All @@ -235,6 +238,7 @@ extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool
extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid);
extern Oid get_constraint_typid(Oid conoid);


/* extension.c - forward declarations */
extern bool IsDropCitusExtensionStmt(Node *parsetree);
extern List * GetDependentFDWsToExtension(Oid extensionId);
Expand Down
1 change: 1 addition & 0 deletions src/include/distributed/deparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ extern char * DeparseAlterExtensionStmt(Node *stmt);

/* forward declarations for deparse_database_stmts.c */
extern char * DeparseAlterDatabaseOwnerStmt(Node *node);
extern char * DeparseGrantOnDatabaseStmt(Node *node);

/* forward declaration for deparse_publication_stmts.c */
extern char * DeparseCreatePublicationStmt(Node *stmt);
Expand Down
Loading

0 comments on commit 8d3a06c

Please sign in to comment.